【问题标题】:Splitting one table based on criteria and comparing根据条件拆分一张表并进行比较
【发布时间】:2012-01-12 16:13:55
【问题描述】:

我不太确定表达这个特定查询的最佳方式,所以我希望标题足够,但是,我将尝试描述我需要能够理解如何做的内容。澄清一下,这是针对 oracle sql 的。

我们有一个名为评估的表格。此表中有不同类型的评估,但是,某些评估应按照逻辑顺序并在设定的时间范围内跟随其他评估。当客户有多个相同类型的评估时,问题就会出现,因为我们必须在 excel 中使用效率相当低的数组公式来确定哪个“完整”评估与“初始”评估相对应。

我有一个较早的查询已在此站点 (Returning relevant date from multiple tables including additional table info) 上解决,我认为其中包含许多所需逻辑(特别是在识别在指定时间范围内发生的相应事件时)。然而,虽然该查询从 3 个单独的表(评估、事件、责任)中提取数据,但我现在需要创建一个查询,该查询生成类似的结果,但从 1 个主表和第二个表中提取以返回工作人员信息。我认为最合乎逻辑的方法是创建一个查询,该查询使用一种评估类型查看评估表,然后再次加入评估表(可能是临时表?),评估类型将遵循最初的评估类型。

例如:

表 1(评估):

Client    ID    Assessment Type   Start       End
P1        1     Initial           01/01/2012  05/01/2012

表 2(评估温度?):

Client ID    Assessment Type   Start       End
P1     2     Full              12/01/2012 

表 3:

ID     Worker     Team
1      Bob        Team1
2      Lyn        Team2

结果:

Client  ID    Initial Start    Initial End    Initial Worker   Full Start   Full End   
P1      1     01/01/2012       05/01/2012     Bob              12/01/2012

所以表 1 和表 2 取自同一张表,只是它带回了不同的评估。理想情况下,将进行检查以确保“完整​​”评估在“初始”评估结束后的 X 天内开始(类似于前面提到的前一个查询中的“可能”检查)。如果可以实现这一点,可能值得一提的是,我也有兴趣将其扩展到查看多种评估类型,因为大致在周期中,客户可能会进行 4 或 5 种不同类型的评估。任何指点都将不胜感激,我已经从这个社区获得了很多帮助,这非常有价值。

编辑:

根据 MB 的建议进行了编辑以包含解决方案。

Select
*
From(
Select
I.ASM_SUBJECT_ID as PNo,
I.ASM_ID As IAID,
I.ASM_QSA_ID as IAType,
I.ASM_START_DATE as IAStart,
I.ASM_END_DATE as IAEnd,
nvl(olm_bo.get_ref_desc(I.ASM_OUTCOME,'ASM_OUTCOME'),'') as IAOutcome,
C.ASM_ID as CAID,
C.ASM_QSA_ID as CAType,
C.ASM_START_DATE as CAStart,
C.ASM_END_DATE as CAEnd,
nvl(olm_bo.get_ref_desc(C.ASM_OUTCOME,'ASM_OUTCOME'),'') as CAOutcome,
ROUND(C.ASM_START_DATE -I.ASM_START_DATE,0) as "Likely",
row_number() over(PARTITION BY  I.ASM_ID                   
ORDER BY 
abs(I.ASM_START_DATE -  C.ASM_START_DATE))as "Row Number"
FROM
O_ASSESSMENTS I
left join O_ASSESSMENTS C
on I.ASM_SUBJECT_ID = C.ASM_SUBJECT_ID
and C.ASM_QSA_ID  IN ('AA523','AA1326') and
ROUND(C.ASM_START_DATE - I.ASM_START_DATE,0) >= -2
AND
ROUND(C.ASM_START_DATE -  I.ASM_START_DATE,0) <= 25
and C.ASM_OUTCOME <>'ABANDON'
Where I.ASM_QSA_ID  IN ('AA501','AA1323')
AND I.ASM_OUTCOME <> 'ABANDON'
AND
I.ASM_END_DATE >= '01-04-2011') WHERE "Row Number" = 1 

【问题讨论】:

  • 在您的示例中找到完整开始的条件是什么,表之间没有匹配的字段?
  • 抱歉,评估表中应该有一个客户 ID,用于将评估链接在一起,但它也依赖于初始结束之间的固定天数和核心的开始 - 即间隔不超过 +/- 20 天。

标签: sql oracle


【解决方案1】:

您可以在 SQL 中的给定查询中多次访问同一个表,只需使用表别名即可。所以这样做的一种方法是:

select i.client,
       i.id     initial_id,
       i.start  initial_start,
       i.end    initial_end,
       w.worker initial_worker,
       f.id     full_id,
       f.start  full_start,
       f.end    full_end
from assessments i
join workers w on i.id = w.id
left join assessments f 
       on i.client = f.client and 
          f.assessment_type = 'Full' and
          f.start between i.end and i.end + X 
/* replace X with appropriate number of days */
where i.assessment_type = 'Initial'

注意:诸如end(Oracle SQL 中的保留字)之类的列名通常应该用双引号引起来,但从上一个问题来看,这些似乎是实际列名的简化版本。

【讨论】:

  • 谢谢,这是有道理的,我已经能够将它与我以前的查询集成。我以为会是这样,但不太明白怎么做 - 现在我明白了,谢谢!
【解决方案2】:

从您的帖子中,我假设您在这里使用 Oracle(正如我在问题中看到的“Oracle”)。

就“临时”表而言,我们想到了视图。 Oracle 视图可以为您提供表的不同外观,这听起来就像您正在寻找不同类型的评估。

Don Burleson 是任何有关 Oracle 的好消息来源,他在 http://www.dba-oracle.com/concepts/views.htm 上提供了一些有关 Oracle 视图的提示

【讨论】:

  • 谢谢,我会看看这个,看看我能不能理解它!
猜你喜欢
  • 2020-11-11
  • 1970-01-01
  • 2020-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
相关资源
最近更新 更多