sql - 日期范围内的 GROUP BY 和聚合

标签 sql sql-server tsql

SELECT IsConfirmed, IsNetConfirmed, d.FullDate FROM Final.FactApplication f 
INNER JOIN final.DimOfferedDate d on f.OfferedDateKey= d.OfferedDateKey
WHERE d.CalendarYear in ('2013','2014','2015')

上面的代码返回以下示例数据。

IsConfirmed IsNetConfirmed  FullDate
----------------------------------------------  
1           0               2013-01-04 00:00:00.000   
1           1               2013-02-04 00:00:00.000
0           1               2013-03-04 00:00:00.000
1           0               2013-04-04 00:00:00.000

我希望汇总每年的天数和月数的 IsConfirmed 和 IsNetConfirmed 的总和,以便我最终得到以下结果。我需要每年汇总,以便 4/31/2012 的总和包括 1/1/2012-4/31/2012 之间的数据。 enter image description here

到目前为止,这是我的代码 - 但我无法理解所有分组。请帮忙。

SELECT sum(IsConfirmed) AS ConfirmCount
    ,sum(IsNetConfirmed) AS NetConfirmCount
    ,year(d.fulldate) AS cyear
    ,month(d.fulldate) AS cmonth
    ,day(d.fulldate) AS cday
FROM final.FactApplicationHistory f
INNER JOIN final.DimOfferedDate d ON f.OfferedDateKey = d.OfferedDateKey
WHERE d.CalendarYear IN ('2013','2014','2015')
GROUP BY year(d.fulldate)
    ,month(d.fulldate)
    ,day(d.fulldate)
ORDER BY year(d.fulldate)

最佳答案

运行总和很棘手。你不能真的只用一个分组来完成它们。有几种方法可以做到这一点。一种方法是在所有小于或等于当前记录值的记录上将数据表与自身连接起来,并对数据点求和。由于您还想旋转数据,因此您的查询特别复杂。以下是使用表连接方法的方法:

;with temp (IsConfirmed, IsNetConfirmed, FullDate) AS
(
SELECT IsConfirmed, IsNetConfirmed, FullDate
FROM final.FactApplicationHistory f
INNER JOIN final.DimOfferedDate d 
ON f.OfferedDateKey = d.OfferedDateKey
WHERE d.CalendarYear IN ('2013','2014','2015')
)
, pivottable (cmonthday,cmonth,cday,ConfirmCount2013,NetConfirmCount2013,ConfirmCount2014,NetConfirmCount2014,ConfirmCount2015,NetConfirmCount2015) AS
(
    SELECT
        dateadd(day,cday,(DATEADD(month, cmonth, 0))) cmonthday,
        cmonth,
        cday,
        sum(isnull([2013],0)) ConfirmCount2013, 
        sum(isnull([2016],0)) NetConfirmCount2013, 
        sum(isnull([2014],0)) ConfirmCount2014, 
        sum(isnull([2017],0)) NetConfirmCount2014, 
        sum(isnull([2015],0)) ConfirmCount2015, 
        sum(isnull([2018],0)) NetConfirmCount2015
    FROM 
        (SELECT sum(IsConfirmed) AS ConfirmCount
            ,sum(IsNetConfirmed) AS NetConfirmCount
            ,year(d.FullDate) AS cyear
            ,year(d.FullDate)+3 AS cyear2
            ,month(d.FullDate) AS cmonth
            ,day(d.FullDate) AS cday
        FROM #temp d
        WHERE year(FullDate) IN ('2013','2014','2015')
        GROUP BY year(d.FullDate)
            ,month(d.FullDate)
            ,day(d.FullDate)
        ) ps
    PIVOT
    (
    SUM (ConfirmCount)
    FOR cyear IN
    ( [2013],[2014],[2015])
    ) AS pvt
    PIVOT
    (
    SUM (NetConfirmCount)
    FOR cyear2 IN
    ( [2016],[2017],[2018])
    ) AS pvt
    Group by cmonth,
        cday
)
select
    pivottable.cmonth,
    pivottable.cday,
    sum(RunningSums.ConfirmCount2013) ConfirmCount2013, 
    sum(RunningSums.NetConfirmCount2013) NetConfirmCount2013, 
    sum(RunningSums.ConfirmCount2014) ConfirmCount2014, 
    sum(RunningSums.NetConfirmCount2014) NetConfirmCount2014, 
    sum(RunningSums.ConfirmCount2015) ConfirmCount2015, 
    sum(RunningSums.NetConfirmCount2015) NetConfirmCount2015
from pivottable
join pivottable RunningSums
on RunningSums.cmonthday <= pivottable.cmonthday
group by pivottable.cmonth,pivottable.cday
order by pivottable.cmonth, pivottable.cday

我想这甚至可能是游标实际上是个好主意的情况。您可以将输出数据透视表创建到表中,然后遍历每条记录并使用运行总和更新每个值。对于包含数百万条记录的非常大的表,这可能比我的自连接方法更有效。

关于sql - 日期范围内的 GROUP BY 和聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29685798/

相关文章:

SQLzoo 更多 JOIN 练习 #16

sql-server - SSRS 错误 - “报表项表达式只能引用当前数据集范围内的字段,或者如果在聚合内

c# - SQL/C# : DataTable to stored procedure (INSERT from user-defined table type) - Converting error

sql - 存储过程 - 功能性能差异

php - MySQL - PHP - 用户 '' @'localhost' 访问数据库 'myproject' 被拒绝

Sql Server Express 数据库大小限制

SQL根据数量复制行

sql - 在 T-SQL 中根据列的连续日期创建两列

sql - 加入具有多个匹配项的表,但只带回指定的匹配项

SQL反向列值查询