Циклы в SQL Server Management Studio - PullRequest
0 голосов
/ 01 мая 2019

Мне дан список из 717 SKU, которые мне нужно пройти и сложить итоговые значения продаж за год и единиц. Я разработал код для поиска SKU по годам и получения общей суммы. Мне было интересно, если бы был способ, которым я мог бы зациклить, чтобы ввести большее количество SKU, чтобы мне не пришлось проходить индивидуальный SKU по SKU.

Я знаком с утверждениями Loop, но не лучшим образом выполняю их. Интересно, есть ли способ сделать это в Microsoft SQL Server Management Studio 2017.

Я пытался объявить и повторить код, но он оказался неэффективным.

DECLARE @SDate date
SET @SDate = '01/01/2018'
DECLARE @EDate date
SET @EDate = '12/31/2018'
DECLARE @Sku varchar(20)
SET @Sku = 'SN1580' 


SELECT        SUM(Amount) AS EXPR1
FROM            dbo.[Threshold Enterprises$Sales Invoice Line]
WHERE        ([Shipment Date] BETWEEN @SDate AND @EDate) AND (No_ = N'SN1580')
SELECT        SUM(Quantity) AS EXPR1
FROM            dbo.[Threshold Enterprises$Sales Invoice Line]
WHERE        ([Shipment Date] BETWEEN @SDate AND @EDate) AND (No_ = N'SN1580')

SELECT        SUM(Amount) AS EXPR1
FROM            dbo.[Threshold Enterprises$Sales Invoice Line]
WHERE        ([Shipment Date] BETWEEN @SDate AND @EDate) AND (No_ = N'SN0350')
SELECT        SUM(Quantity) AS EXPR1
FROM            dbo.[Threshold Enterprises$Sales Invoice Line]
WHERE        ([Shipment Date] BETWEEN @SDate AND @EDate) AND (No_ = N'SN0350')

Ожидайте, что результаты дадут мне что-то вроде

SN1234
Amount 1000
Sum 200

SN3456
Amount 2000
Sum 100

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

Ответы [ 3 ]

5 голосов
/ 01 мая 2019

Если вам нужно передать несколько SKU, вы можете использовать табличную переменную:

DECLARE @SDate date
SET @SDate = '01/01/2018'
DECLARE @EDate date
SET @EDate = '12/31/2018'

DECLARE @Skus table (SKU varchar(20);

INSERT INTO @SKUs
VALUES('SN1580'),
      ('SN0350');

SELECT SIL.[No_] AS SKU,
       SUM(SIL.Amount) AS Amount,
       SUM(SIL.Quanity) AS Quantity
FROM dbo.[Threshold Enterprises$Sales Invoice Line] SIL --I recommeond against special characters (including white space) in object names
     JOIN @SKUs S ON SIL.[No_] = S.SKU
WHERE SIL.[Shipment Date] BETWEEN @SDate AND @EDate
GROUP BY SIL.[No_];

Если это приложение, использующее этот параметризованный запрос, вам может потребоваться создать определенный пользователем тип таблицы и затем использоватьчто:

CREATE TYPE dbo.SKUs AS TABLE (SKU varchar(20));

В документации Microsoft описано, как их использовать в Табличных параметрах .

Изменить, примечание, если в вашем столбце [Shipment Date] есть обе датыи значения времени (и время может быть значением, отличным от 00:00:00), которое я предлагаю против BETWEEN.Это происходит потому, что в любое время после полуночи последнего дня между этими двумя датами не будет.Например, 2018-04-30 00:00:00.003 не находится между 2018-04-01 и 2018-04-30.

Если у вас действительно есть значения даты и времени, я предлагаю использовать это предложение:

WHERE SIL.[Shipment Date] >= @SDate
  AND SIL.[Shipment Date] < DATEADD(DAY, 1, @EDate)
2 голосов
/ 01 мая 2019

Не думай с точки зрения петель. Думайте с точки зрения наборов.

Здесь используется переменная таблицы для списка sku, но вы можете использовать CTE, фактическую таблицу, список VALUE; все, что действительно позволяет SQL Server обрабатывать все ваши поисковые термины как набор данных, а не как отдельные входные данные.

DECLARE @SDate date = '01/01/2018'
DECLARE @EDate date = '12/31/2018'

DECLARE @Sku TABLE
(
  Sku varchar(20)
);

INSERT @Sku (Sku)
VALUES (N'SN1580'),
       (N'SN0350'); --<--Add your list here. Maybe use Excel to make the wrappers.

SELECT        
   l.No_ 
  ,SUM(l.Amount) AS Amount
  ,SUM(l.Quantity) AS Quantity
FROM 
  dbo.[Threshold Enterprises$Sales Invoice Line] AS l
  JOIN
   @Sku AS s
    ON s.Sku = l.No_
WHERE
  l.[Shipment Date] BETWEEN @SDate AND @EDate
GROUP BY
  l.No_
2 голосов
/ 01 мая 2019

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

SELECT      No_ AS SKU, SUM(Amount) AS Amount, SUM(Quantity) AS Quantity
FROM        dbo.[Threshold Enterprises$Sales Invoice Line]
WHERE       ([Shipment Date] BETWEEN @SDate AND @EDate) 
            AND (No_ IN 
                ('SN1580', 'SN0350')
            )
GROUP BY No_;

Или, если у вас есть SKU в таблице, вы можете изменить IN на:

            AND (No_ IN 
                (Select SKU from yourTableHere)
            )
...