Новое в SQL. Хотел бы преобразовать формулу Excel IF (COUNTIFS ()) в код SQL и сделать так, чтобы SQL вычислял ее вместо Excel - PullRequest
0 голосов
/ 26 марта 2019

Я использую SQL Server 2008 R2 (окончательная первоначальная версия).

У меня есть SQL-запрос, который запрашивает даты, продукты, клиентов и единицы:

select 

[Transaction Date] as Date, 
[SKU] as Product, 
[Customer Name] as Customer, 
sum(Qty) as Units 

from dataset

where [Transaction Date] < '2019-03-01' and [Transaction Date] >= '2016-01-01'

group by [Transaction Date], [SKU], [Customer Name]

order by [Transaction Date]

Это тянет сотни тысяч записей, и я хотел определить, была ли определенная транзакция новым заказом или переупорядочением, основываясь на следующей логике:

Изменение порядка: конкретный клиент заказал этот конкретный продукт за последние 6 месяцев

Новый заказ: этот конкретный клиент не заказывал этот конкретный продукт в течение последних 6 месяцев

Для этого у меня есть эта формула в Excel, которая, кажется, работает:

=IF(COUNTIFS(A$1:A1,">="&DATE(YEAR(A2),MONTH(A2)-6,DAY(A2)),C$1:C1,C2,B$1:B1,B2),"Reorder","New Order")


Формула работает, когда я вставляю ее по отдельности или в меньший набор данных, но когда я пытаюсь скопировать и вставить ее во все строки размером 500K +, Excel сдается, потому что она повторяется для каждого вычисления.

Скорее всего, это можно сделать в SQL, но у меня нет знаний о том, как преобразовать эту формулу Excel в SQL, я только начал изучать ее.

Ответы [ 3 ]

1 голос
/ 26 марта 2019

У вас все хорошо с началом запроса.Есть три дополнительные функции, которые вы хотите добавить в свой запрос.

Первое, что вам нужно, это самое простое.GETDATE() просто возвращает текущую дату.Это понадобится вам при сравнении текущей даты с датой транзакции.

Вторая функция - DATEDIFF, которая даст вам единицу времени между двумя датами (месяцами, днями, годами,четверти и т. д.).Используя DATEDIFF, вы можете сказать «это дата за последние 6 месяцев».Формат для этого довольно прост.Это DATEDIFF(interval, date1, date2).

Требуемая функция thrid - это CASE, которая позволяет вам указать SQL, что вы получите один ответ, если выполняется одно условие, и другой ответ, если другое условиевстретились.Например, вы можете сказать: «Если разница в днях <60, верните« Порядок », если не укажите« Новый заказ »».</p>

Собираем все вместе:

SELECT CASE 
        WHEN DATEDIFF(MONTH, [Transaction Date], GETDATE()) <= 6
            THEN 'Reorder'
        ELSE 'New Order'
        END as ORDER_TYPE
    ,[Transaction Date] AS DATE
    ,[SKU] AS PRODUCT
    ,[Customer Name] AS CUSTOMER
    ,Qty AS UNITS
FROM DATASET
0 голосов
/ 26 марта 2019

Если я правильно понимаю, вы хотите достичь пика на предыдущую дату и сделать сравнение. Это предполагает lag():

select (case when lag([Transaction Date]) over (partition by SKU, [Customer Name] order by [Transaction Date]) >
                  dateadd(month, -6, [Transaction Date])
             then 'Reorder'
             else 'New Order'
        end) as Order_Type
       [Transaction Date] as Date, 
       [SKU] as Product, 
       [Customer Name] as Customer, 
       sum(Qty) as Units 
from dataset d
group by [Transaction Date], [SKU], [Customer Name];

EDIT:

В SQL Server 2008 вы можете эмулировать LAG(), используя OUTER APPLY:

select (case when dprev.[Transaction Date] >
                  dateadd(month, -6, d.[Transaction Date])
             then 'Reorder'
             else 'New Order'
        end) as Order_Type
       d.[Transaction Date] as Date, 
       d.[SKU] as Product, 
       d.[Customer Name] as Customer, 
       sum(d.Qty) as Units 
from dataset d outer apply
     (select top (1) dprev.*
      from dataset dprev
      where dprev.SKU = d.SKU and
            dprev.[Customer Name] = d.[Customer Name] and
            dprev.[Transaction Date] < d.[Transaction Date]
      order by dprev.[Transaction Date] desc
     ) dprev
group by d.[Transaction Date], d.[SKU], d.[Customer Name];
0 голосов
/ 26 марта 2019
SELECT CASE
         WHEN Datediff(day, [transaction date], Getdate()) <= 180 THEN 'reorder'
         ELSE 'Neworder'
       END,
       [transaction date] AS Date,
       [sku]              AS Product,
       [customer name]    AS Customer,
       qty                AS Units
FROM   datase  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...