SQL查询最大日期列

时间:2014-12-23 21:18:17

标签: sql oracle oracle11g greatest-n-per-group

如果我的代码输入不正确,我道歉。我正在尝试查询将返回最新bgcheckdate和状态报告的表格。该表包含每条记录的其他bgcheckdates和状态,但在我的报告中,我只需要查看最新的bgcheckdate及其状态。

SELECT BG.PEOPLE_ID, MAX(BG.DATE_RUN) AS DATERUN, BG.STATUS
FROM PKS_BGCHECK BG
GROUP BY BG.PEOPLE_ID, BG.status;

当我运行上述查询时,我仍然会看到具有多个背景检查日期和状态的查询。

然而,当我在没有状态的情况下运行时,它可以正常工作:

SELECT BG.PEOPLE_ID, MAX(BG.DATE_RUN)
FROM PKS_BGCHECK BG
GROUP BY BG.PEOPLE_ID;

所以只是想知道是否有人可以帮助我找出帮助我查询日期运行和状态,并反映最新日期。

2 个答案:

答案 0 :(得分:1)

最佳解决方案取决于您使用的RDBMS。

这是一个基本的标准SQL:

SELECT bg.PEOPLE_ID, bg.DATE_RUN, bg.STATUS
FROM  (
   SELECT PEOPLE_ID, MAX(DATE_RUN) AS MAX_DATERUN
   FROM   PKS_BGCHECK
   GROUP  BY PEOPLE_ID
   ) sub
JOIN PKS_BGCHECK bg ON bg.PEOPLE_ID = sub.PEOPLE_ID
                   AND bg.DATE_RUN = sub.MAX_DATERUN;

但如果存在关系,则每PEOPLE_ID可以获得多行。

Oracle ,Postgres或SQL Server及其他(但不是MySQL)中,您还可以使用窗口函数row_number()

WITH cte AS (
   SELECT PEOPLE_ID, DATE_RUN, STATUS
        , ROW_NUMBER() OVER(PARTITION BY PEOPLE_ID ORDER BY DATE_RUN DESC) AS rn
   FROM   PKS_BGCHECK
   )
SELECT PEOPLE_ID, DATE_RUN, STATUS
FROM   cte
WHERE  rn = 1;

这保证每PEOPLE_ID 1行。关系是任意解决的。向ORDER BY添加更多表达式以确定性地打破关系。

在Postgres中,最简单的解决方案是使用DISTINCT ON

这个相关答案的详情:

答案 1 :(得分:0)

选择时间敏感集中的最新行非常简单,并且在很大程度上与平台无关:

SELECT BG.PEOPLE_ID, BG.DATE_RUN, BG.STATUS
FROM   PKS_BGCHECK BG
WHERE  BG.DATE_RUN =(
        SELECT MAX( DATE_RUN )
        FROM   PKS_BGCHECK
        WHERE  PEOPLE_ID = BG.PEOPLE_ID
          AND  DATE_RUN < SYSDATE );

如果PK是(PEOPLE_ID,DATE_RUN),查询将以与任何其他方法一样快的速度执行。如果他们没有形成PK(为什么不?),那么使用它们形成一个独特的索引。但我确定你已经做过其中一种了。

顺便说一下,如果你不允许输入未来的日期,那么你真的不需要子查询的and部分。一些时间实现允许将来的日期(计划或预定的事件),所以我习惯于添加它。