我試圖弄清楚如何在 SQL Server 中最好地執行以下操作。
假設我有一張桌子Sales:
| 姓名 | 銷售量 | 日期 |
|---|---|---|
| 彼得 | 1 | 1-1-22 |
| 本 | 2 | 1-2-22 |
| 莎莉 | 3 | 1-1-22 |
| 本 | 2 | 2-2-22 |
| 彼得 | 1 | 2-1-22 |
| 莎莉 | 2 | 2-2-22 |
| 彼得 | 1 | 3-1-22 |
| 本 | 2 | 3-2-22 |
| 莎莉 | 2 | 3-2-22 |
我的目標是我希望能夠跟蹤從年初到今天的每一天,直到今天的所有銷售額的總和。
所以它應該從 2022 年 1 月 1 日到 2022 年 4 月 1 日每天顯示。舉個例子,從 1/3 到 1/31 每天的銷售額,它應該為 Peter 顯示 1,Ben 為 2,Sally 為 3,但是到 2/3 時,它應該顯示 Ben 為 4,Peter 為 2,和 5 給莎莉。今天日期的行應該為 Peter 顯示 3,為 Ben 顯示 6,為 Sally 顯示 7。
非常感謝任何幫助或指導!
謝謝!
uj5u.com熱心網友回復:
鑒于此示例資料(請使用明確的日期格式!):
CREATE TABLE dbo.SalesData(Name varchar(32), Sales int, Date date);
INSERT dbo.SalesData(Name, Sales, Date) VALUES
(N'Peter', 1, '20220101'),
(N'Ben', 2, '20220102'),
(N'Sally', 3, '20220101'),
(N'Ben', 2, '20220202'),
(N'Peter', 1, '20220201'),
(N'Sally', 2, '20220202'),
(N'Peter', 1, '20220301'),
(N'Ben', 2, '20220302'),
(N'Sally', 2, '20220302');
我們可以使用遞回 CTE 來獲取從年初到現在的所有日期,交叉連接 sales 表中的個人姓名以獲取每個銷售人員每個日期的一行,然后使用視窗子句獲取標準運行總計迄今為止,每個人:
DECLARE @today date = GETDATE();
DECLARE @yearstart date = DATEFROMPARTS(YEAR(@today), 1, 1);
;WITH Days([day]) AS
(
SELECT @yearstart UNION ALL
SELECT DATEADD(DAY, 1, [day]) FROM Days
WHERE [day] < @today
),
AllDatesPerPerson AS
(
SELECT Days.[day], sd.Name FROM Days
CROSS JOIN (SELECT DISTINCT Name FROM dbo.SalesData
WHERE Date >= @yearstart) AS sd
)
SELECT dpp.Name, dpp.[day], COALESCE(SUM(sd.Sales) OVER
(PARTITION BY dpp.Name ORDER BY dpp.[day] ROWS UNBOUNDED PRECEDING),0)
FROM AllDatesPerPerson AS dpp
LEFT OUTER JOIN dbo.SalesData AS sd
ON dpp.Name = sd.Name AND sd.Date = dpp.[day]
ORDER BY dpp.Name, dpp.[day]
OPTION (MAXRECURSION 366); -- covers up to Dec 31 even on leap years
- 示例
這可能是一個很好的面試問題,因為它聽起來很簡單,但編碼有點棘手。源查詢獲取日期串列、賣家串列和 SaleCount,如果沒有記錄銷售則為零。我們需要一個視窗函式( SUM ... OVER )以獲得運行總計,而不僅僅是當天的總計。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/454746.html
