Sql server SQL server分组依据,求和并检索列值

Sql server SQL server分组依据,求和并检索列值,sql-server,group-by,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

我想对名为“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
然后,我想对分组行的所有“pay”值求和,选择最近的时间戳和与最近的时间戳相对应的“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。我假设您的代码中存在
main\u 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:

这就是窗口函数派上用场的地方。在上面使用SUM()而不是group by,然后在上面使用ROW_NUMBER(),您可以选择所需的行并获得聚合的总和


SQL Fiddle:

这可能是错误的,但您似乎没有获得ID,因为您没有选择它。是的,我没有选择它-当我选择时,我会收到一个错误,因为它不在“分组依据”中。这是我需要帮助的部分。谢谢。这几乎是100%,我发现的唯一问题是,当我有记录时,我试图按相同的4列和相同的时间戳进行分组。然后我得到了比我应该得到的更多的唱片。提琴:是的,这只有在四列可以确定唯一性的情况下才有效。在你的情况下,@Matt的答案会更有效。用10万张桌子测试,效果很好。非常感谢。
;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