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
我想 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