Это - вопрос об эффективности SQL.
Некоторое время назад я должен был записать набор запросов для получения по запросу данных из ERP-системы. Большинство из них было достаточно просто, но один из них привел к довольно неэффективному запросу и его прослушиванию меня с тех пор, как как там получен, чтобы быть лучшим путем.
Проблема не сложна. У Вас есть строки данных о сбыте. В каждой строке у Вас есть количество, продажная цена и код продавца, среди другой информации.
Комиссии платят на основе ступившей скользящей шкалы. Чем больше они продают, тем лучше комиссия. Шаги могли бы быть 1000, 10000, 10 000$ и т.д. Проблема реального мира более сложна, но вот именно по существу это.
Единственным путем я нашел выполнения, это должно было сделать что-то вроде этого (очевидно, не реальный запрос)
select qty, price, salesman,
(select top 1 percentage from comissions
where comisiones.salesman = saleslines.salesman
and saleslines.qty > comisiones.qty
order by comissiones.qty desc
) percentage
from saleslines
это приводит к корректной комиссии, но страшно тяжело.
Существует ли лучший способ сделать это? Я не ищу кого-то для перезаписи моего sql, больше 'смотрит как foobar запросы', и я могу взять его оттуда.
Реальная структура комиссии может быть указана для различных продавцов, статей и клиентов и даже дат продаж. Это также время от времени изменяется, таким образом, все должно управляться по условию в таблицах..., т.е. я не могу поместить зафиксированные диапазоны в sql. Текущий запрос возвращает приблизительно 3-400000 строк и берет приблизительно 20-30 secs. К счастью его единственным, используемым ежемесячно, но замедление, является вид прослушивания меня.
Это находится на mssql.
Ian
править:
Я должен был дать более сложный пример с начала. Я понимаю теперь, когда мой начальный пример пропускает несколько существенных элементов сложности, извинений всем.
Это может лучше получить его
select client-code, product, product-family, qty, price, discount, salesman,
(select top 1 percentage from comissions
where comisiones.salesman = saleslines.salesman
and saleslines.qty > comisiones.qty
and [
a collection of conditions which may or may not apply:
Exclude rows if the salesman has offered discounts above max discounts
which appear in each row in the commissions table
There may be a special scale for the product family
There may be a special scale for the product
There may be a special scale for the client
A few more cases
]
order by [
The user can control the order though a table
which can prioritize by client, family or product
It normally goes from most to least specific.
]
) percentage
from saleslines
само собой разумеется, за реальным запросом не легко следовать. Только для создания жизни более интересной ее именование является много языком.
Таким образом для каждой строки salesline комиссия может отличаться.
Это может звучать чрезмерно сложным, но если бы Вы думаете, как Вы заплатили бы комиссии, это имеет смысл. Вы не хотите платить кому-то за продажу материала с высокими скидками, Вы также хотите смочь предложить конкретному клиенту скидку на конкретный продукт, если они покупают X единиц. Продавец должен заработать больше, если они продают больше.
Во всем вышеупомянутом я исключаю ограниченные специальные предложения даты.
Я думаю, что разделы могут быть решением, но я должен исследовать это более всестороннее, поскольку я ничего не знаю о разделах. Его данный я несколько идей.
Если вы используете версию SQL Server, которая поддерживает выражения общих таблиц, такие как SQL Server 2005 и новее, более эффективным решением может быть:
With RankedCommissions As
(
Select SL.qty, SL.price, SL.salesman, C.percentage
, Row_Number() Over ( Partition By SL.salesman Order By C.Qty Desc ) As CommissionRank
From SalesLines As SL
Join Commissions As C
On SL.salesman = C.salesman
And SL.qty > C.qty
)
Select qtr, price, salesman, percentage
From RankedCommissions
Where CommissionRank = 1
Если вам нужно учесть возможность того, что для данного продавца нет значений комиссионных, где SalesLine.Qty> Commission.Кол-во, тогда вы можете сделать что-то вроде:
With RankedCommissions As
(
Select SL.qty, SL.price, SL.salesman, C.percentage
, Row_Number() Over ( Partition By SL.salesman Order By C.Qty Desc ) As CommissionRank
From SalesLines As SL
Join Commissions As C
On SL.salesman = C.salesman
And SL.qty > C.qty
)
Select SL.qtr, SL.price, SL.salesman, RC.percentage
From SalesLines As SL
Left Join RankedCommissions As RC
On RC.salesman = SL.salesman
And RC.CommissionRank = 1
select
qty, price, salesman,
max(percentage)
from saleslines
inner join comissions on commisions.salesman = saleslines.salesman and
saleslines.qty > comissions.qty
group by
qty, price, salesman