【问题标题】:Select rows containing the group-wise maximum of a column选择包含列的分组最大值的行
【发布时间】:2014-09-07 08:26:54
【问题描述】:

假设我有一个名为 Item 的表,其中包含设置在某个日期的价格的项目。

物品

id | date       | price
---+------------+------
1  | 2014-01-01 | 1.09
1  | 2014-03-15 | 1.19
2  | 2014-04-02 | 2.75
1  | 2014-07-28 | 0.99
2  | 2014-08-07 | 2.35
3  | 2014-10-21 | 3.90

现在我想选择每件商品的当前价格(每件商品的最后记录):

WITH lastChange AS (
    SELECT id, MAX(date) date
    FROM Item
    GROUP BY id
)

SELECT Item.id, Item.price
FROM Item
JOIN lastChange ON Item.id = lastChange.id AND Item.date = lastChange.date

给予:

id | price
---+------
1  | 0.99
2  | 2.35
3  | 3.90

我想知道是否有更好的方法来进行此选择。

【问题讨论】:

  • 如果有两行 id 和 date 相同但价格不同的行怎么办?
  • 假设这不会发生。这是一个简化的例子。我也可以添加包括毫秒在内的时间,但我猜这并不能让问题更清楚。
  • 基本问题很清楚:“如何选择包含一列的分组最大值的整行”。仔细考虑如何处理一组中有多个最新价格的情况。如果您不希望它发生,请在表上使用 UNIQUE 约束。

标签: sql-server sql-server-2008


【解决方案1】:

窗口函数

WITH t AS (
  SELECT *
   ,MAX(date) OVER(PARTITION BY id) max_date_by_id
  FROM Item
)
SELECT *
FROM t
WHERE date = max_date_by_id

交叉申请

SELECT *
FROM Item t
CROSS APPLY (
  SELECT MAX(date) max_date_by_id
  FROM Item
  WHERE id = t.id
)
WHERE date = max_date_by_id

【讨论】:

  • 我更喜欢窗口函数而不是我自己的解决方案和交叉应用,因为这提供了更多选项以防查询变得更复杂,例如sqlfiddle.com/#!6/a8d4c/1/0
猜你喜欢
  • 1970-01-01
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多