从多个表返回相关日期,包括附加表信息

时间:2011-12-23 11:06:04

标签: sql oracle date join

这是从先前通过stackoverflow(Returning nearest date to date in a different table)解决的查询继续进行的,但是,我现在希望进一步开发它。

我的SQL是:

SELECT *
FROM (SELECT O_ASSESSMENTS.ASM_SUBJECT_ID as "P Number", 
             O_ASSESSMENTS.ASM_ID as "Assessment ID", 
             O_ASSESSMENTS.ASM_START_DATE as "Assessment Start",  
             O_ASSESSMENTS.ASM_END_DATE as "Assessment End", 
             O_SERVICE_EVENTS.SEV_ID as "Event ID", 
             O_SERVICE_EVENTS.SEV_ACTUAL_DATE as "Event Start", 
             O_SERVICE_EVENTS.SEV_OUTCOME_DATE as "Event End",
             ROUND(O_ASSESSMENTS.ASM_START_DATE -O_SERVICE_EVENTS.SEV_ACTUAL_DATE,0) as "Likely",
             row_number() over(PARTITION BY  O_ASSESSMENTS.ASM_ID                                    
                               ORDER BY abs(O_ASSESSMENTS.ASM_START_DATE -  O_SERVICE_EVENTS.SEV_ACTUAL_DATE))as "Row Number"            
      FROM O_ASSESSMENTS 
      JOIN O_SERVICE_EVENTS
        ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID
      Where O_SERVICE_EVENTS.SEV_CODE IN ('ICS_E3','CPINVEST') AND 
            O_ASSESSMENTS.ASM_QSA_ID  IN ('AA1329','AA521') )
WHERE "Row Number" = 1

基本上,我们有两个表--o_assessments和o_service_events,这个SQL将最近的服务事件返回给评估。现在我想在查询中包含一些更多的上下文信息,以使其对最终用户更有帮助 - 即团队名称和工作者名称。

不幸的是,团队和工作人员再次在不同的表中(o_responsibilities),并通过asm_id链接到o_assessments到res_rec_id。

问题是,我真的不确定如何将这个表调用到上面的sql中 - 所以任何建议都会非常感激!

我还想知道是否有可能调整现有查询以仅在“可能”字段具有0的差异时返回相应的事件(因为任何更大的可能与该特定评估无关)。我知道我可以将它添加到where,但如果我添加行

and "Likely" = 0

它只返回一个事件的评估,这不会突出显示任何问题(即没有相应事件的评估)。

我一直在学习SQL,但目前看来我手头上还有很多东西,所以任何建议都非常感谢!我不确定是要修改原始查询还是开始新查询,所以我希望我不会无意中侵犯任何规则。

编辑:

好的,按照Mark的解决方案,这就是我的工作。

SELECT 
* 
FROM 
(SELECT 
OAS.ASM_SUBJECT_ID as "P Number",
OAS.ASM_ID as "Assessment ID",
OAS.ASM_START_DATE as "Assessment Start", 
OAS.ASM_END_DATE as "Assessment End",
OAS.ASM_AUTH_DATETIME as "Authorisation Date",
nvl(olm_bo.get_ref_desc(OAS.ASM_OUTCOME,'ASM_OUTCOME'),'') as "Outcome",
nvl(olm_bo.get_org_name(ORE.RES_PARTY_OUN_ID),'') as "Team",
nvl(olm_bo.get_per_name(ORE.RES_PARTY_ID),'') as "Worker",
OSE.SEV_ID as "Event ID",
OSE.SEV_ACTUAL_DATE as "Event Start",
OSE.SEV_OUTCOME_DATE as "Event End",
ROUND(OAS.ASM_START_DATE -OSE.SEV_ACTUAL_DATE,0) as "Likely",
row_number() over(PARTITION BY  OAS.ASM_ID                   
ORDER BY 
abs(OAS.ASM_START_DATE -  OSE.SEV_ACTUAL_DATE))as "Row Number"
FROM O_ASSESSMENTS OAS      
INNER JOIN O_RESPONSIBILITIES ORE ON OAS.ASM_ID = ORE.RES_REC_ID
AND ORE.RES_PARTY_OUN_ID = 'TEAM'
LEFT JOIN O_SERVICE_EVENTS OSE ON OAS.ASM_SUBJECT_ID = OSE.SEV_SUBJECT_ID 
AND            
OSE.SEV_CODE IN ('EVENT') 
AND             
ROUND(OAS.ASM_START_DATE - OSE.SEV_ACTUAL_DATE,0) >= -7
AND
ROUND(OAS.ASM_START_DATE - OSE.SEV_ACTUAL_DATE,0) <= 7
Where OAS.ASM_QSA_ID  IN ('ACODE')
AND
nvl(olm_bo.get_ref_desc(OAS.ASM_OUTCOME,'ASM_OUTCOME'),'') <> 'Abandon' ) WHERE "Row Number" = 1 

3 个答案:

答案 0 :(得分:1)

开始一个新的是正确的行动方针;编辑问题以“添加范围”不是一个好习惯。这属于“添加范围”,因此一个新问题是正确的方法。

SELECT
ID, "Assessment ID", 
"Assessment Start", "Assessment End", "Event ID", 
"Event Start", "Event End", Likely, Team_name, Worker_name
FROM
  (SELECT 
  O_ASSESSMENTS.ASM_SUBJECT_ID as "ID", 
  O_ASSESSMENTS.ASM_ID as "Assessment ID", 
  O_ASSESSMENTS.ASM_START_DATE as "Assessment Start",  
  O_ASSESSMENTS.ASM_END_DATE as "Assessment End", 
  O_SERVICE_EVENTS.SEV_ID as "Event ID", 
  O_SERVICE_EVENTS.SEV_ACTUAL_DATE as "Event Start", 
  O_SERVICE_EVENTS.SEV_OUTCOME_DATE as "Event End",
  ROUND(O_ASSESSMENTS.ASM_START_DATE -O_SERVICE_EVENTS.SEV_ACTUAL_DATE,0) as "Likely",
  row_number() over(PARTITION BY  O_ASSESSMENTS.ASM_ID                                    
    ORDER BY abs(O_ASSESSMENTS.ASM_START_DATE -  
    O_SERVICE_EVENTS.SEV_ACTUAL_DATE))    as "Row    Number",
  RES.TEAM_NAME,
  RES.WORKER_NAME
  FROM O_ASSESSMENTS 
  INNER JOIN  O_SERVICE_EVENTS
    ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID
  INNER JOIN O_Responsibilities res 
    ON O_Assessments.ASM_ID = res.res_rec_ID
  WHERE O_SERVICE_EVENTS.SEV_CODE IN ('ICS_E3','CPINVEST')
    AND O_ASSESSMENTS.ASM_QSA_ID IN ('AA1329','AA521') )  InnerTable
WHERE "Row Number" = 1 and (Likely = 0 or LIKELY is null)

我在这里所做的只是

  1. 在内部选择语句
  2. 上添加加入条件
  3. 包含您要求的列,但未提供姓名,因此我在INNER和OUTER选择语句中假设了TEAM_NAME和WORKER_NAME
  4. 在对原始帖子的评论之前的联接之前消除了AND
  5. 在内部选择中添加了表名的别名,需要加入连接 在某些时候到外桌。
  6. 将(可能= 0或可能为空)添加到外部where子句
  7. 重新格式化SQL以保持可读性。
  8. 以上5,可能不太正确,我不完全理解您对没有服务日期的评估的评论。如果是这种情况,如果您想要所有评估和相关服务(如果存在),则评估和服务之间的连接必须是左连接,而不是INNER。目前,您只获得具有相关服务的评估。如果您需要所有评估,可能需要进行其他更改。

    因此...

      FROM O_ASSESSMENTS 
      INNER JOIN  O_SERVICE_EVENTS
        ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID
    

    将成为(仅改为内部左侧)

      FROM O_ASSESSMENTS 
      LEFT JOIN  O_SERVICE_EVENTS
        ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID
    

    它假设评估总是有责任记录,如果不是那么也需要LEFT加入。

    最后,当SEV_Actual_Date为空时,需要考虑当你为LIKELY做什么结果。应该有什么价值?

答案 1 :(得分:1)

尝试:

SELECT *
FROM (SELECT OAS.ASM_SUBJECT_ID as "P Number", 
             OAS.ASM_ID as "Assessment ID", 
             OAS.ASM_START_DATE as "Assessment Start",  
             OAS.ASM_END_DATE as "Assessment End", 
             ORE.TEAM,
             ORE.WORKER,
             OSE.SEV_ID as "Event ID", 
             OSE.SEV_ACTUAL_DATE as "Event Start", 
             OSE.SEV_OUTCOME_DATE as "Event End",
             ROUND(OAS.ASM_START_DATE -OSE.SEV_ACTUAL_DATE,0) as "Likely",
             row_number() over(PARTITION BY  OAS.ASM_ID                                    
                               ORDER BY abs(OAS.ASM_START_DATE -  OSE.SEV_ACTUAL_DATE))as "Row Number"            
      FROM O_ASSESSMENTS OAS
      LEFT JOIN O_RESPONSIBILITIES ORE
        ON OAS.ASM_ID = ORE.RES_REC_ID
      LEFT JOIN O_SERVICE_EVENTS OSE
        ON OAS.ASM_SUBJECT_ID = OSE.SEV_SUBJECT_ID AND
           OSE.SEV_CODE IN ('ICS_E3','CPINVEST') AND 
           ROUND(OAS.ASM_START_DATE - OSE.SEV_ACTUAL_DATE,0) = 0
      Where OAS.ASM_QSA_ID  IN ('AA1329','AA521') )
WHERE "Row Number" = 1

请注意,这假设RES_REC_ID是O_RESPONSIBILITIES上的唯一标识符。

答案 2 :(得分:0)

您可以将o_responsibilities加入相应ID的内嵌视图,然后在查询中包含其列。

请注意,您需要将where likely = 0位放在外部查询中(使用行号标准),而不是内联视图,因为likely是别名。如果您想要突出显示没有事件的评估,那么您应该执行left join并添加sev_id is null的条件。

这样的事情可以解决问题:

select  *
from   (select    o_assessments.asm_subject_id                      as "P Number", 
                  o_assessments.asm_id                              as "Assessment ID", 
                  o_assessments.asm_start_date                      as "Assessment Start",  
                  o_assessments.asm_end_date                        as "Assessment End", 
                  o_service_events.sev_id                           as "Event Id", 
                  o_service_events.sev_actual_date                  as "Event Start", 
                  o_service_events.sev_outcome_date                 as "Event End",
                  o_responsibilities.[WHATEVER]                     as "Team/Worker Stuff",
                  round(o_assessments.asm_start_date - o_service_events.sev_actual_date,0)
                                                                    as "Likely",
                  row_number() over (partition by o_assessments.asm_id                                    
                                     order by     abs(o_assessments.asm_start_date - o_service_events.sev_actual_date))
                                                                    as rn
        from      o_assessments 
        left join o_service_events
        on        o_service_events.sev_subject_id                    = o_assessments.asm_subject_id
        left join o_responsibilities
        on        o_responsibilities.res_rec_id                      = o_assessments.asm_id
        where     o_service_events.sev_code                         in ('ICS_E3','CPINVEST')
        and       o_assessments.asm_qsa_id                          in ('AA1329','AA521'))
where   rn = 1
and    (likely = 0 or sev_id is null);