我有以下查询,显示特定日期范围的每周总计:
declare @from_date datetime
declare @to_date datetime
SET @from_date = '2014-03-30';
SET @to_date = '2014-08-10';
SELECT DATEDIFF(week, 0, IDOC.Import_Date) Week,
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) 'From Date',
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) + 6 'End Date',
COUNT(IDOC.IDOC_ID) 'Total'
FROM IDOC
INNER JOIN dbo.File_Type FI
on IDOC.File_Type_ID = FI.File_Type_ID
INNER JOIN IDOC_Team_Assignment ITA
ON IDOC.IDOC_ID=ITA.IDOC_ID
Where IDOC.Import_Date BETWEEN @from_date AND @to_date
GROUP BY DATEDIFF(week, 0, IDOC.Import_Date)
ORDER BY DATEDIFF(week, 0, IDOC.Import_Date)
输出:
Week | From Date | End Date | Total
--------------------------------------------------
5965 2014-04-28 2014-05-04 1
5967 2014-05-12 2014-05-18 1
5968 2014-05-19 2014-05-25 2
我想添加累计总数(运行总计)这是我想要完成的事情:
Week | From Date | End Date | Total | Cummulative
-------------------------------------------------------------
5965 2014-04-28 2014-05-04 1 1
5967 2014-05-12 2014-05-18 1 2
5968 2014-05-19 2014-05-25 2 4
答案 0 :(得分:1)
xQbert给你的链接向你展示了这个概念,但当你的选择中已经有另一个 count 时,它可能会有点混乱。
您需要删除组,并在计数上使用 over ,限制一个只计算 分组你已经拥有,第二个覆盖整个范围。
在这种情况下,您不能使用行前未绑定,因为它将为每一行创建一个条目,而不是在现有结果集上构建。但您确实需要在 over 和选择结束时保持顺序。
您还需要添加 distinct 关键字。
SELECT DISTINCT
DATEDIFF(week, 0, IDOC.Import_Date) Week,
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) 'From Date',
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) + 6 'End Date',
COUNT(IDOC.IDOC_ID) OVER (PARTITION BY DATEDIFF(week, 0, IDOC.Import_Date)) 'Total',
COUNT(IDOC.IDOC_ID) OVER (ORDER BY DATEDIFF(week, 0, IDOC.Import_Date)) 'Running Total'
FROM IDOC
INNER JOIN dbo.File_Type FI
on IDOC.File_Type_ID = FI.File_Type_ID
INNER JOIN IDOC_Team_Assignment ITA
ON IDOC.IDOC_ID=ITA.IDOC_ID
WHERE IDOC.Import_Date BETWEEN @from_date AND @to_date
ORDER BY DATEDIFF(week, 0, IDOC.Import_Date)
我无法在SQL Server 2008上对此进行测试,但我确实在VS2013免费试用了它,我知道它可以在Oracle中运行。值得一试。
这个在SQL Server 2008 R2上测试过 - 我希望你不急于获得这些数据......
SELECT
DATEDIFF(week, 0, IDOC.Import_Date) Week,
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) 'From Date',
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) + 6 'End Date',
COUNT(IDOC.IDOC_ID) 'Total',
(
SELECT
COUNT(aIDOC.IDOC_ID)
FROM
IDOC aIDOC
INNER JOIN dbo.File_Type aFI
ON aIDOC.File_Type_ID = aFI.File_Type_ID
INNER JOIN IDOC_Team_Assignment aITA
ON aIDOC.IDOC_ID=aITA.IDOC_ID
WHERE
aIDOC.Import_Date BETWEEN @from_date AND @to_date
AND DATEDIFF(week, 0, IDOC.Import_Date) <= DATEDIFF(week, 0, aIDOC.Import_Date)
) 'RunningTotal'
FROM
IDOC
INNER JOIN dbo.File_Type FI
ON IDOC.File_Type_ID = FI.File_Type_ID
INNER JOIN IDOC_Team_Assignment ITA
ON IDOC.IDOC_ID=ITA.IDOC_ID
WHERE
IDOC.Import_Date BETWEEN @from_date AND @to_date
GROUP BY
DATEDIFF(week, 0, IDOC.Import_Date)
ORDER BY
DATEDIFF(week, 0, IDOC.Import_Date)
现在我把它变成了一个看起来更干净的CTE。
WITH CTE( WeekNbr, FromDate, EndDate, Total) AS (
SELECT
DATEDIFF(week, 0, IDOC.Import_Date) 'WeekNbr',
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) 'FromDate',
DATEADD(week, DATEDIFF(week, 0, IDOC.Import_Date), 0) + 6 'EndDate',
COUNT(IDOC.IDOC_ID) 'Total'
FROM
IDOC
INNER JOIN dbo.File_Type FI
ON IDOC.File_Type_ID = FI.File_Type_ID
INNER JOIN IDOC_Team_Assignment ITA
ON IDOC.IDOC_ID=ITA.IDOC_ID
WHERE
IDOC.Import_Date BETWEEN @from_date AND @to_date
GROUP BY
DATEDIFF(week, 0, IDOC.Import_Date)
)
SELECT
A.WeekNbr,
A.FromDate,
A.EndDate,
A.Total,
(SELECT SUM(B.Total) FROM CTE B WHERE B.WeekNbr <= A.WeekNbr) 'RunningTotal'
FROM
CTE A
ORDER BY
A.WeekNbr