SQL Server GROUP BY,SUM和检索列值

时间:2018-01-31 17:45:19

标签: sql-server group-by

我想针对名为“report”的SQL Server表运行SQL查询

表格:

id     timestamp           num     subid   country        name        pay

1   1/30/2018  1:32         1       11        us          John        1.00
2   1/30/2018  1:40         1       11        us          John        1.00
3   1/30/2018  1:31         1       12        us          Smith       1.00
4   1/30/2018  1:31         1       12        us          Jan         1.00
5   1/30/2018  1:45         1       12        us          Jan         1.00

期望的结果:

2   1/30/2018  1:40         1       11        us          John        2.00
3   1/30/2018  1:31         1       12        us          Smith       1.00
5   1/30/2018  1:45         1       12        us          Jan         2.00

我想要什么 - 我想通过以下4列进行分组:

num     subid   country   name

然后我想总结分组行的所有“付费”值,选择最近的时间戳和“id”,它对应于最近的时间戳。

我正在努力寻找“id”

我的查询:

SELECT num, subid, country, name, 
SUM(pay) as pay_sum, MAX(timestamp) as timestamp_max, 
FROM report 
GROUP BY main_id, subid, country, name;

它提供了除ID之外我需要的一切。

问题 - 如何获取分组行的ID,其中id是与最新时间戳匹配的ID?

2 个答案:

答案 0 :(得分:2)

;WITH cte AS (
    SELECT
       id
       ,timestamp
       ,num
       ,subid
       ,country
       ,name
       ,SUM(pay) OVER (PARTITION BY num, subid, country, name) as pay
       ,ROW_NUMBER() OVER (PARTITION BY num, subid, country, name ORDER BY timestamp DESC) as RowNum
    FROM
       report
)

SELECT *
FROM
    cte
WHERE
    RowNum = 1

这是窗口函数派上用场的地方。使用SUM()OVER而不是group by然后使用ROW_NUMBER()OVER,然后你可以选择你想要的行并获得总和。

SQL小提琴:http://sqlfiddle.com/#!18/6b0c6/5

答案 1 :(得分:0)

有几种方法可以做到这一点。对于这个,我使您的查询成为子查询,然后进行自我加入以获取ID。我假设你的代码中有main_id = num

select
    table1.id,
    sub.*
from (
    SELECT 
        num, 
        subid, 
        country, 
        name, 
        SUM(pay) as pay_sum, 
        MAX(timestamp) as timestamp_max
    FROM table1
    GROUP BY num, subid, country, name
) as sub
join table1
    on table1.subid = sub.subid
    and table1.timestamp = sub.timestamp_max
    and table1.name = sub.name
    and table1.country = sub.country

 ;

sql fiddle:http://sqlfiddle.com/#!18/76be8/7