SQL 仅返回具有较晚日期的行

Posted

技术标签:

【中文标题】SQL 仅返回具有较晚日期的行【英文标题】:SQL return the row ONLY with the later date 【发布时间】:2013-06-14 02:25:21 【问题描述】:

我在一个表中有以下行:

user_id school_id graduation_date 
------- --------- ---------------
1             123      2006-05-19 
1             123      2008-05-19
2             123      2006-05-19
2             123      2008-05-19

我有以下疑问:

SELECT * FROM user_school us, [user] u
WHERE us.user_id = u.user_id
AND us.school_id = 123

我想在最后添加一个子句,只返回一个单行;具有最新毕业日期的行 - 所以在这种情况下,是两行中的第二行。我希望能够让每个学生排一排。因此,每个学生的最新毕业日期。

编辑 - 请记住,这是一个带有许多 JOINS 的 VERY LARGE 查询的精简版本...执行 TOP 和 ORDER BY 是不够的。我需要一个 GREATEST(date) 函数之类的东西。

【问题讨论】:

【参考方案1】:

鉴于您对 TOP 和 ORDER BY 的限制,您不能一口气完成这些。

您可以找到最近的毕业日期,然后找到它所在的行。

SELECT *
FROM (
  SELECT user_id,
         school_id,
         row_number() over (partition by user_id order by graduation_date desc) position
  FROM user_school
) us,
[user] u
WHERE us.user_id = u.user_id
  AND position = 1 /* limits to highest graduation date */

【讨论】:

这似乎更接近我正在寻找的东西。现在就试试吧。 我希望每个学生都能获得一排。因此,每个学生的最新毕业日期。我该怎么做? 我假设你提到的三列是 user_school 表上的唯一列?没有代理键?假设没有,我会更新。这会使事情复杂化,但仍然可以做到。 如果您愿意更改您选择的表格,Tom 在下面的回答实际上比我的要好。如果您的“外部”查询需要使用此表,那么我的将起作用。但我绝对更喜欢汤姆的。它更简单。【参考方案2】:

最简单的方法是使用row_number()

select *
from (SELECT *,
             row_number() over (partition by us.user_id
                                order by graduation_date desc) as seqnum
      FROM user_school us join
           [user] u
           on us.user_id = u.user_id
      where us.school_id = 123
     ) t
where seqnum = 1

【讨论】:

【参考方案3】:

老实说,我不确定我是否理解这个问题,但根据我得到的,这应该可以解决问题

SELECT TOP 1 * FROM user_school us, [user] u
WHERE us.user_id = u.user_id
AND us.user_id = 1
ORDER BY u.graduation_date DESC

【讨论】:

哈,很抱歉你在我编辑之前回答了这个问题。请参见上文。 这在一个简单的情况下确实有效,但我不只是按该行过滤。 你不能只是SELECT TOP 1 FROM 为简洁起见,省略了许多其他连接和列。有没有办法专门针对该日期列执行此操作? 您只想要一个结果行还是多行?【参考方案4】:

使用ORDER BYLIMIT

SELECT TOP 1 * FROM user_school us, [user] u 
WHERE us.user_id = u.user_id AND us.user_id = 1 
ORDER BY u.graduation_date DESC 

【讨论】:

为简洁起见,省略了许多其他连接和列。有没有办法专门针对该日期列执行此操作? @GordonLinoff 感谢您的收获。出于某种原因,我认为我正在使用 mysql 来解决这个问题。我编辑了 MS SQL 的答案。 @AdamLevitt 抱歉,我无法回答您。【参考方案5】:

你想要这样的东西:

SELECT
 field1,
 field2, 
 ...
   (SELECT MAX(graduation_date)
                       FROM user_school
                       WHERE user_id = us.user_id) as max_grad_date
FROM
 student_table_name

【讨论】:

以上是关于SQL 仅返回具有较晚日期的行的主要内容,如果未能解决你的问题,请参考以下文章

将按日期较早/较晚的最近相邻行返回到另一个表的日期

仅返回一列中的日期与另一列中的日期最接近的行?

SQL选择具有最大和最小日期的行

SQL BigQuery - 插入具有不同日期范围的行

Oracle SQL 选择具有开始和结束日期的行,如果某些重叠合并行

从每组中的 3 个表中选择 sql 中具有最新日期的行