T-SQL,按一列分组,取两列最大值

T-SQL, get highest values from two columns while grouping by one column

我想 select 每个 ID 的最高价格,但只有具有最高 lastupdated 列的行的价格。

使用此查询不会给我正确的价格。

SELECT 
    id, MAX(price) as price, MAX(lastupdated) as lastupdated 
FROM 
    tbl 
GROUP BY 
    id

样本表数据:

id, price, lastupdated
1, 50, 2015-03-01
1, 51, 2015-03-01
1, 52, 2015-03-01
1, 53, 2015-02-28
1, 54, 2015-02-28
1, 55, 2015-02-28
2, 20, 2015-02-01
2, 21, 2015-02-01
2, 22, 2015-02-01
2, 33, 2015-01-28
2, 34, 2015-01-28
2, 35, 2015-01-28

我想要的结果是:

id, price, lastupdated
1, 52, 2015-03-01
2, 22, 2015-02-01

您可以使用过滤 join 只查看具有最新日期的行:

SELECT  tbl.id
,       MAX(price) as price
,       lastupdated 
FROM    Tel
JOIN    (
        SELECT  id
        ,       MAX(last_updated) as maxupdated
        FROM    tbl
        GROUP BY
                id
        ) mx
ON      tbl.id = mx.id
        AND tbl.lastupdated = mx.maxupdated
GROUP BY 
        tbl.id
,       last_updated

您需要找到每个 id 的 lastupdated 并加入:

SELECT tbl.id, MAX(price) as price, m.lastupdated
FROM tbl 
JOIN (
    SELECT id, MAX(lastupdated) AS lastupdated 
    FROM tbl 
    GROUP BY id
) m ON tbl.id = m.id and tbl.lastupdated = m.lastupdated
GROUP BY tbl.id, m.lastupdated
ORDER BY tbl.id

您可以使用 RANK 为您 table 的每条记录分配一个排名编号。然后在外部查询中使用此数字 select 具有每个 id 的最新 lastupdated 值的所有记录:

SELECT id, MAX(price) as price, lastupdated
FROM (
   SELECT id, price, lastupdated,
          RANK() OVER (PARTITION BY id ORDER BY lastupdated DESC) AS rnk
   FROM tbl ) t  
WHERE t.rnk = 1 
GROUP BY id, lastupdated

或者,您可以使用 HAVING 子句过滤掉任何 (id, lastupdated) 没有最大 lastupdated 日期值的组:

SELECT id, MAX(price) as price, lastupdated
FROM #tbl t1
GROUP BY id, lastupdated
HAVING lastupdated = (SELECT MAX(lastupdated) FROM #tbl t2 WHERE id = t1.id) 

使用 HAVING 子句的查询更简洁但效率较低,因为它使用的子查询 (SELECT MAX(lastupdated) ...) 对每个组 计算一次 在外部查询中定义。

今天觉得cte是个不错的方法

with cte ( id, maxdate )
as
(
  select id, max(lastupdated)
  from tbl
  group by id
)
select 
     t3.id
    ,max(price)
    ,max(maxdate)
from 
    tbl t3 
        inner join cte on t3.id = cte.id and t3.lastupdated = cte.maxdate
group by
    t3.id