从两个表中的一个中选择最新记录

时间:2015-03-09 21:35:37

标签: sql oracle

我试图根据另一个表中的主键从两个表中的一个中选择一条记录。所以一个“MASTER”表和另外两个表,另外两个表各有一个FK JOB_ID和一个带日期的列。对于给定的作业ID,我想根据这两个表中的一个表中的最新日期来获取记录。示例(我知道,表和列的名称和值没有多大意义,这些都是假数据但你会明白这一点)。这两个额外的表中有很多列我需要包含在结果中,这是为了简单起见。它也在Oracle中。

JOB_TABLE

JOB_ID    JOB_NAME      JOB_ASSIGN
1         A job         Tom
2         Another job   Shawn
3         And another   Jason

JOB_SUB_1_TABLE

JOB_ID    SUB_JOB_ID     COMPLETION_DATE
1         1              03/09/2015
1         2              03/08/2015
2         1              <null>
3         1              02/28/2015
3         2              03/01/2015

JOB_SUB_2_TABLE

JOB_ID    SUB_JOB_ID   START_DATE
1         3             03/08/2015
1         4             01/06/2015
2         2             03/07/2015
3         3             03/10/2015

有了这些数据,我希望结果是:

JOB_ID    JOB_NAME      JOB_ASSIGN     SUB_JOB_ID     DATE
1         A job         Tom            1              03/09/2015
2         Another job   Shawn          2              03/07/2015
3         And another   Jason          3              03/10/2015

我能得到的最接近的是:

SELECT JOB_ID,
       JOB_NAME,
       JOB_ASSIGN,
       SUB_JOB_ID,
       DATE
FROM   (SELECT JOB_ID,
               JOB_NAME,
               JOB_ASSIGN,
               SUB_JOB_ID,
               COMPLETION_DATE AS "DATE"
        FROM   JOB_SUB_1_TABLE
        WHERE  completion_date IN(SELECT Max(competion_date)
                                  FROM   JOB_SUB_1_TABLE
                                  GROUP  BY job_id,
                                            sub_job_id)
        UNION
        SELECT JOB_ID,
               JOB_NAME,
               JOB_ASSIGN,
               SUB_JOB_ID,
               START_DATE AS "DATE"
        FROM   JOB_SUB_2_TABLE
        WHERE  completion_date IN(SELECT Max(competion_date)
                                  FROM   JOB_SUB_2_TABLE
                                  GROUP  BY job_id,
                                            sub_job_id)) 

2 个答案:

答案 0 :(得分:2)

您也可以通过这种方式解决问题。正如Faber所建议的那样nulls last是导致3/7/15出现而不是作业2的空值

select x.job_id,
       y.job_name,
       y.job_assign,
       x.sub_job_id,
       x.completion_date as dt
  from (select x.*,
               row_number() over(  partition by job_id
                                       order by completion_date desc
                                                nulls last
                                ) as rn
          from (select *
                  from job_sub_1_table
                union all
                select *
                  from job_sub_2_table) x) x
  join job_table y
    on x.job_id = y.job_id
 where x.rn = 1

小提琴测试: http://sqlfiddle.com/#!4/175060/2/0

答案 1 :(得分:1)

您可以对日期进行排名。由于您有两个相似的详细信息表,您可以将它们联合起来,在主表上将它们连接起来,然后在两个子表中对日期进行排名。结果看起来应该类似于:

SELECT  X.JOB_ID, 
        X.JOB_NAME, 
        X.JOB_ASSIGN,
        X.SUB_JOB_ID,
        X.JOB_DATE,
FROM  ( SELECT  T.JOB_ID, 
                T.JOB_NAME, 
                T.JOB_ASSIGN,
                ST.SUB_JOB_ID,
                ST.JOB_DATE,
                DENSE_RANK() 
                  OVER ( PARTITION BY T.JOB_ID 
                         ORDER BY ST.JOB_DATE DESC) AS DATERANK

        FROM    JOB_TABLE T
        JOIN (  SELECT  JOB_ID, 
                        SUB_JOB_ID, 
                        COMPLETION_DATE AS JOB_DATE
                FROM    JOB_SUB_1_TABLE ST1
                UNION ALL
                SELECT  JOB_ID, 
                        SUB_JOB_ID, 
                        START_DATE 
                FROM    JOB_SUB_2_TABLE ST2
              ) ST ON ST.JOB_ID = T.JOB_ID
      ) X
WHERE
  X.DATERANK = 1