Мне дан список из 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
Или, если бы был способ получить результаты в формате, который можно легко экспортировать, чтобы преуспеть.
3 ответа
Не думайте с точки зрения петель. Думайте с точки зрения наборов.
При этом для списка 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_
Если вам нужно передать несколько 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)
Вы должны быть в состоянии сделать все это в одном запросе, используя оператор 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)
)
Похожие вопросы
Новые вопросы
sql-server
Microsoft SQL Server - это система управления реляционными базами данных (RDBMS). Используйте этот тег для всех выпусков SQL Server, включая Compact, Express, Azure, Fast-track, APS (ранее PDW) и Azure SQL DW. Не используйте этот тег для других типов СУБД (MySQL, PostgreSQL, Oracle и т. Д.). Не используйте этот тег для проблем, связанных с разработкой программного обеспечения и мобильных устройств, если только он не связан напрямую с базой данных.