SQL sub запросы - является там лучшим путем

Это - вопрос об эффективности 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 единиц. Продавец должен заработать больше, если они продают больше.

Во всем вышеупомянутом я исключаю ограниченные специальные предложения даты.

Я думаю, что разделы могут быть решением, но я должен исследовать это более всестороннее, поскольку я ничего не знаю о разделах. Его данный я несколько идей.

6
задан Ian 22 June 2010 в 16:02
поделиться

2 ответа

Если вы используете версию 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
3
ответ дан 17 December 2019 в 18:10
поделиться
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
0
ответ дан 17 December 2019 в 18:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: