Sql Server 按时间间隔分组连接零值

标签 sql sql-server left-join

我有一个以下形式的表,其中包含日期时间列和 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

Demo here

关于Sql Server 按时间间隔分组连接零值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42922603/

相关文章:

SQL Server更新列比较跨行的值

sql-server - 合并语句错误调试

MySQL 多个左连接在一张表上

php - 将变量上传到sql查询

mysql - 如何根据其他表的数据在sql中查询更新

sql - 如何从临时表选择中删除第一列

MySQL 使用 GROUP BY 按日期排序

MySQL 多行连接

sql - SAS:如何在多个级别上计算不同

sql - 我将如何批量更新日期和时间?