我写了一个查询来获取personID的每个日期的总和 我想做的是使用存储过程将结果插入到新表中,我的查询类似于参考(使用 AdventureWorks2019(
WITH TOP7 AS
(
SELECT
SOH.SalesPersonID, SOH.OrderDate,
SUM(SOH.TotalDue) AS Total,
ROW_NUMBER() OVER (PARTITION BY SOH.SalesPersonID ORDER BY SOH.OrderDate DESC) AS RowNum
FROM
Sales.SalesOrderHeader AS SOH
LEFT JOIN
Sales.SalesOrderHeader AS SOH2 ON SOH.SalesOrderID = SOH2.SalesOrderID
WHERE
SOH.SalesPersonID IS NOT NULL
GROUP BY
SOH.OrderDate, SOH.SalesPersonID
)
(
SELECT SalesPersonID, OrderDate, Total, RowNum
FROM TOP7
WHERE RowNum <= 7
)
这是我得到的输出:
ID Date Total RowNum
----------------------------------------------------
274 2014-05-01 00:00:00.000 42546.9235 1
274 2014-03-31 00:00:00.000 110623.7157 2
274 2014-03-01 00:00:00.000 46525.3068 3
274 2014-01-29 00:00:00.000 1592.5736 4
274 2013-11-30 00:00:00.000 79835.0276 5
274 2013-09-30 00:00:00.000 102227.2339 6
274 2013-08-30 00:00:00.000 2194.914 7
275 2014-05-01 00:00:00.000 417208.4727 1
275 2014-03-31 00:00:00.000 273730.5071 2
275 2014-03-01 00:00:00.000 221438.2289 3
275 2014-01-29 00:00:00.000 279451.2658 4
我想做的是将结果插入到一个新表中,如下所示
ID, Fdate, Ftotal, Sdate, Stotal, Tdate, Ttotal, Fdate, Ftotal, Fidate, Fitotal, Sidate, Sitotal, Sedate, Stotal
274 | 2014-05-01 | 42546.9235 | 2014-03-31 | 110623.7157 | 2014-03-01 | 46525.3068 | 2014-01-29 | 1592.5736 | 2013-11-30 | 79835.0276 | 2013-09-30 | 102227.2339 | 2013-08-30 | 2194.914
我正在使用 SQL Server。
我想为结果中的所有 Id 执行此操作 - 我如何实现?
提前谢谢你
编辑:
我这样做是为了插入到新表中
WITH TOP7 AS
(
SELECT
SOH.SalesPersonID, SOH.OrderDate,
SUM(SOH.TotalDue) AS Total,
ROW_NUMBER() OVER (PARTITION BY SOH.SalesPersonID ORDER BY SOH.OrderDate DESC) AS RowNum
FROM
Sales.SalesOrderHeader AS SOH
LEFT JOIN
Sales.SalesOrderHeader AS SOH2 ON SOH.SalesOrderID = SOH2.SalesOrderID
WHERE
SOH.SalesPersonID IS NOT NULL
GROUP BY
SOH.OrderDate, SOH.SalesPersonID
)
INSERT INTO [Person].[WeekEmployeeTotals] ([PersonID]
,[FirstDate]
,[FirstDateTotal]
,[SecondDate]
,[SecondDateTotal]
,[ThirdDate]
,[ThirdDateTotal]
,[FourthDate]
,[FourthDateTotal]
,[FifthDate]
,[FifthDateTotal]
,[SixthDate]
,[SixthDateTotal]
,[SeventhDate]
,[SeventhDateTotal])
SELECT SalesPersonID,
Date1 = MAX(CASE WHEN RowNum = 1 THEN OrderDate END),
Total1 = SUM(CASE WHEN RowNum = 1 THEN Total END),
Date2 = MAX(CASE WHEN RowNum = 2 THEN OrderDate END),
Total2 = SUM(CASE WHEN RowNum = 2 THEN Total END),
Date3 = MAX(CASE WHEN RowNum = 3 THEN OrderDate END),
Total3 = SUM(CASE WHEN RowNum = 3 THEN Total END),
Date4 = MAX(CASE WHEN RowNum = 4 THEN OrderDate END),
Total4 = SUM(CASE WHEN RowNum = 4 THEN Total END),
Date5 = MAX(CASE WHEN RowNum = 5 THEN OrderDate END),
Total5 = SUM(CASE WHEN RowNum = 5 THEN Total END),
Date6 = MAX(CASE WHEN RowNum = 6 THEN OrderDate END),
Total6 = SUM(CASE WHEN RowNum = 6 THEN Total END),
Date7 = MAX(CASE WHEN RowNum = 7 THEN OrderDate END),
Total7 = SUM(CASE WHEN RowNum = 7 THEN Total END)
FROM TOP7
WHERE RowNum <= 7
GROUP BY SalesPersonID;
但我有一个问题,如何设置选择要插入的内容,我的意思是这样的
Create PROCEDURE [dbo].[InsertFromSHO]
@PID INT,
@D1 datetime,
@T1 numeric(24,7),
@D2 datetime,
@T2 numeric(24,7),
@D3 datetime,
@T3 numeric(24,7),
@D4 datetime,
@T4 numeric(24,7),
@D5 datetime,
@T5 numeric(24,7),
@D6 datetime,
@T6 numeric(24,7),
@D7 datetime,
@T7 numeric(24,7)
AS
SET @D1 = (SELECT Date1 = MAX(CASE WHEN RowNum = 1 THEN OrderDate END) FROM TOP7 WHERE RowNum <= 7)
^ 我知道这是错误的,但这就是我要做的,因为我将来需要做很多事情,所以我需要知道一个好方法来实现这一目标
可以使用条件聚合在所需的输出中获取结果
WITH TOP7 AS
(
SELECT
SOH.SalesPersonID, SOH.OrderDate,
SUM(SOH.TotalDue) AS Total,
ROW_NUMBER() OVER (PARTITION BY SOH.SalesPersonID ORDER BY SOH.OrderDate DESC) AS RowNum
FROM
Sales.SalesOrderHeader AS SOH
LEFT JOIN
Sales.SalesOrderHeader AS SOH2 ON SOH.SalesOrderID = SOH2.SalesOrderID
WHERE
SOH.SalesPersonID IS NOT NULL
GROUP BY
SOH.OrderDate, SOH.SalesPersonID
)
SELECT SalesPersonID,
Date1 = MAX(CASE WHEN RowNum = 1 THEN OrderDate END),
Total1 = SUM(CASE WHEN RowNum = 1 THEN Total END),
Date2 = MAX(CASE WHEN RowNum = 2 THEN OrderDate END),
Total2 = SUM(CASE WHEN RowNum = 2 THEN Total END),
Date3 = MAX(CASE WHEN RowNum = 3 THEN OrderDate END),
Total3 = SUM(CASE WHEN RowNum = 3 THEN Total END),
Date4 = MAX(CASE WHEN RowNum = 4 THEN OrderDate END),
Total4 = SUM(CASE WHEN RowNum = 4 THEN Total END),
Date5 = MAX(CASE WHEN RowNum = 5 THEN OrderDate END),
Total5 = SUM(CASE WHEN RowNum = 5 THEN Total END),
Date6 = MAX(CASE WHEN RowNum = 6 THEN OrderDate END),
Total6 = SUM(CASE WHEN RowNum = 6 THEN Total END),
Date7 = MAX(CASE WHEN RowNum = 7 THEN OrderDate END),
Total7 = SUM(CASE WHEN RowNum = 7 THEN Total END)
FROM TOP7
WHERE RowNum <= 7
GROUP BY SalesPersonID;
DB<>Fiddle 上的示例
但是,以这种格式存储数据可能不是一个好主意,如果您需要经常访问这种格式的数据,最好创建一个视图。我也在这里删除了你的加入,因为这似乎完全没有意义,因为你从来没有引用SOH2
:
CREATE VIEW Top7SalesPivot
AS
WITH TOP7 AS
(
SELECT
SOH.SalesPersonID,
SOH.OrderDate,
SUM(SOH.TotalDue) AS Total,
ROW_NUMBER() OVER (PARTITION BY SOH.SalesPersonID ORDER BY SOH.OrderDate DESC) AS RowNum
FROM
Sales.SalesOrderHeader AS SOH
WHERE
SOH.SalesPersonID IS NOT NULL
GROUP BY
SOH.OrderDate, SOH.SalesPersonID
)
SELECT SalesPersonID,
Date1 = MAX(CASE WHEN RowNum = 1 THEN OrderDate END),
Total1 = SUM(CASE WHEN RowNum = 1 THEN Total END),
Date2 = MAX(CASE WHEN RowNum = 2 THEN OrderDate END),
Total2 = SUM(CASE WHEN RowNum = 2 THEN Total END),
Date3 = MAX(CASE WHEN RowNum = 3 THEN OrderDate END),
Total3 = SUM(CASE WHEN RowNum = 3 THEN Total END),
Date4 = MAX(CASE WHEN RowNum = 4 THEN OrderDate END),
Total4 = SUM(CASE WHEN RowNum = 4 THEN Total END),
Date5 = MAX(CASE WHEN RowNum = 5 THEN OrderDate END),
Total5 = SUM(CASE WHEN RowNum = 5 THEN Total END),
Date6 = MAX(CASE WHEN RowNum = 6 THEN OrderDate END),
Total6 = SUM(CASE WHEN RowNum = 6 THEN Total END),
Date7 = MAX(CASE WHEN RowNum = 7 THEN OrderDate END),
Total7 = SUM(CASE WHEN RowNum = 7 THEN Total END)
FROM TOP7
WHERE RowNum <= 7
GROUP BY SalesPersonID;
这样,您无需在每次添加销售时都更新表。
如果这表现不佳,那么您可能会发现以下索引有所帮助:
CREATE NONCLUSTERED INDEX IX_Sales_SalesOrderHeader__SalesPersonID_OrderDate
ON Sales.SalesOrderHeader (SalesPersonID, OrderDate)
INCLUDE (TotalDue);
不需要光标。SQL是一种基于集合的语言,其中这样的操作很容易在没有循环的情况下执行。您可以只使用insert ... select
语法:
WITH TOP7 AS (
SELECT
SOH.SalesPersonID, SOH.OrderDate,
SUM(SOH.TotalDue) AS Total,
ROW_NUMBER() OVER (PARTITION BY SOH.SalesPersonID ORDER BY SOH.OrderDate DESC) AS RowNum
FROM
Sales.SalesOrderHeader AS SOH
LEFT JOIN
Sales.SalesOrderHeader AS SOH2 ON SOH.SalesOrderID = SOH2.SalesOrderID
WHERE
SOH.SalesPersonID IS NOT NULL
GROUP BY
)
INSERT INTO mytable(ID, Fdate, Ftotal, Sdate, Stotal, Tdate, Ttotal, Fdate, Ftotal, Fidate, Fitotal, Sidate, Sitotal, Sedate, Stotal)
SELECT SalesPersonID, OrderDate, Total, RowNum
FROM TOP7
WHERE RowNum <= 7