我有一个以下形式的表,其中包含日期时间列和 ID 列(请参阅我的其他问题 on SO here )。
Datum SomeID
2017-01-01 07:44:57.840 1
2017-01-02 07:45:10.093 2
2017-01-02 07:45:21.557 3
2017-01-03 09:07:21.253 2
2017-01-05 09:07:42.680 1
2017-01-06 09:07:49.007 5
我的目标是按时间间隔对行进行分组(在本例中不是动态分组,而是按天分组),并计算每天唯一 ID 的数量。我根据 SO 的另一个回复尝试过:
Declare @START datetime2;
Set @START = Cast('2016/05/03' as datetime2);
Declare @END datetime2;
Set @END = Cast('2016/06/03' as datetime2);
WITH CTE_Dates AS
(
SELECT @START AS cte_date
UNION ALL
SELECT DATEPART(Year, DATEADD(DAY, 1, cte_date)) as theYear, DATEPART(MONTH, DATEADD(DAY, 1, cte_date)) as theMonth, DATEPART(DAY, DATEADD(DAY, 1, cte_date)) As theDay
FROM CTE_Dates
WHERE DATEADD(DAY, 1, cte_date) <= @END
)
SELECT
DATEPART(Year, passageTime) as theYear, DATEPART(MONTH, passageTime) as theMonth, DATEPART(DAY, passageTime) As theDay,
ISNULL(COUNT(Distinct batchNbr), 0) AS counted_batchNbr
FROM [prod].[m1218].[passage]
LEFT JOIN CTE_Dates ON DATEADD(dd, 0, DATEDIFF(dd, 0, passageTime)) = cte_date
WHERE passageTime between @START and @END
GROUP BY DATEPART(Year, passageTime), DATEPART(MONTH, passageTime), DATEPART(DAY, passageTime)
ORDER BY theYear, theMonth, theDay
执行时出现以下错误:使用 UNION、INTERSECT 或 EXCEPT 运算符组合的所有查询在其目标列表中必须具有相同数量的表达式。
我认为这是因为我试图在具有 3 列(theYear、theMonth、theDay)的行和单个 datetime2 对象 @Start 之间创建并集。
如何解决这个问题(也许是底部?),以便当我执行查询时,我可以按天获得分组结果,而对于缺失的日子,有一行的计数为零?
最佳答案
试试这个查询:
Declare @START date = '2017-01-01';
Declare @END date = '2017-01-31';
WITH CTE_Dates AS
(
-- Anchor member: create initial values
SELECT @START AS cte_date,
DATEPART(Year, @START) as theYear,
DATEPART(MONTH, @START) as theMonth,
DATEPART(DAY, @START) As theDay
UNION ALL
-- Recursive part: get next day
SELECT DATEADD(DAY, 1, cte_date) AS cte_date,
DATEPART(Year, DATEADD(DAY, 1, cte_date)) as theYear,
DATEPART(MONTH, DATEADD(DAY, 1, cte_date)) as theMonth,
DATEPART(DAY, DATEADD(DAY, 1, cte_date)) As theDay
FROM CTE_Dates
WHERE cte_date <= '2017-01-31'
)
SELECT DATEPART(Year, cte_date) as theYear,
DATEPART(MONTH, cte_date) as theMonth,
DATEPART(DAY, cte_date) As theDay,
ISNULL(COUNT(Distinct [SomeID]), 0) AS counted_batchNbr
FROM CTE_Dates
LEFT JOIN [passage] ON DATEADD(dd, 0, DATEDIFF(dd, 0, [Datum])) = cte_date
WHERE cte_date between @START and @END
GROUP BY DATEPART(Year, cte_date), DATEPART(MONTH, cte_date), DATEPART(DAY, cte_date)
ORDER BY theYear, theMonth, theDay
关于Sql Server 按时间间隔分组连接零值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42922603/