【问题标题】:Selecting max record for each user为每个用户选择最大记录
【发布时间】:2012-08-25 13:46:05
【问题描述】:

这似乎应该相当简单,但我在尝试找到适合我的解决方案时遇到了困难。

我有一个 member_contracts 表,它具有以下(简化的)结构。

MemberID | ContractID   | StartDate | End Date |
------------------------------------------------
1          1              2/1/2002    2/1/2003
2          2              3/1/2002    3/1/2003
3          3              4/1/2002    4/1/2003
1          4              2/1/2002    2/1/2004
2          5              3/1/2003    2/1/2004
3          6              4/1/2003    2/1/2004

我正在尝试创建一个查询,该查询将从该表中选择最新的合同。这是这个小例子的以下输出:

MemberID | ContractID   | StartDate | End Date |
------------------------------------------------
1          4              2/1/2002    2/1/2004
2          5              3/1/2003    2/1/2004
3          6              4/1/2003    2/1/2004

在每个用户的基础上执行此操作非常简单,因为我可以使用子查询来选择指定用户的最大 contractID。我正在使用 SQL Server,所以如果有一种特殊的方式可以使用这种方式,我愿意使用它。就个人而言,我想要与引擎无关的东西。

但是,我将如何编写一个可以为所有用户实现目标的查询?

编辑:我还应该补充一点,我正在寻找每个用户的最大 contractID 值,而不是最近的日期。

【问题讨论】:

  • 您的日期列是 date 还是 varchar 类型?
  • 它们的类型是日期,但实际上,只有合同 ID 的最高值才是重要的。
  • 合约ID是否保证唯一?

标签: sql sql-server subquery


【解决方案1】:

此方案使用 ContractId 字段的唯一性:

SELECT MemberID, ContractID, StartDate, EndDate
FROM member_contracts 
WHERE ContractId IN (
    SELECT MAX(ContractId)
    FROM member_contracts 
    GROUP BY MemberId
)

在线查看:sqlfiddle

【讨论】:

  • 很好,我正在写一个使用 ROW_NUMBER 的答案,但这更简单,适用于 2005 年之前的 SQL Server 版本
  • 完美运行。谢谢!有些东西告诉我,我将来会使用它。
【解决方案2】:

最安全的方法是使用row_number

select MemberId, ContractId, StartDate, EndDate
from (select mc.*,
             row_number() over (partition by MemberId order by contractId desc) seqnum
      from Member_Contracts mc
     ) mc
where seqnum = 1

这处理同一成员的多个合同的情况。 . .这在此数据中可能不是真正的问题。

【讨论】:

  • 太棒了,这似乎是比依赖于唯一的合同 ID 更通用的解决方案。您是否介意详细说明您的查询在这里做什么?就我而言,我想选择最近的记录(如标题所示);我将其放入SQLFiddle 以展示最近的行为。
猜你喜欢
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
相关资源
最近更新 更多