基于单行返回Oracle中所有匹配的行

时间:2015-01-01 21:02:14

标签: sql oracle

想象一个名为resume的表 - 在包含文档的数据库中,每个文档包含许多组件。此表中的行可以是文档本身(文档的元数据),也可以是该文档的组件:

row_id  name        resume_id  last_upd
1       resume_1               2010-1-1
2       section_1   1          2008-12-1
3       section_2   1          2009-6-1
4       resume_2               2010-1-1
5       section_1   4          2014-12-30

在上面的示例中,第1行和第4行是文档本身,其他列包含元数据,第2,3和5行是文档的组件,可以使用resume_id进行映射。

如果其中任何一行(主条目或组件)在一年内更新,我正在尝试从该表返回完整文档(主条目和组件)。如果编辑了文档的任何元素,则只有该行更新了last_upd列。

这是我到目前为止构建的查询,但它很慢,我正在尝试解决如何加快它的速度:

SELECT meta_data.row_id as "resume_id", 
       meta_data.name as "resume_name",
       components.name as "component_name"
FROM 
(
   SELECT DISTINCT(updated_meta_data.row_id) 
   FROM resume updated_meta_data 
   LEFT JOIN resume updated_components ON updated_components.resume_id = updated_meta_data.row_id
   WHERE ((updated_components.last_upd > (SYSDATE - 365)) or (updated_meta_data.last_upd > (SYSDATE - 365)))
) updated_resumes
LEFT JOIN resume meta_data ON updated_resumes.row_id = meta_data.row_id
LEFT JOIN resume components ON components.resume_id = meta_data.row_id

我认为我的查询有效,但如果没有,或者我不清楚我要做什么,我的查询应该返回:

resume_id  resume_name    component_name
4          resume_2       
4          resume_2       section_1

2 个答案:

答案 0 :(得分:1)

以下内容应返回所有"文件"已在过去一年中更新过:

select coalesce(resume_id, row_id)
from resume
group by coalesce(resume_id, row_id)
having last_upd >= sysdate - 365;

要获取完整的组件列表,您可以使用joininexists。然后您可以加入其他信息:

select rs.resume_id, r.name as resume_name, c.name as component_name
from (select coalesce(resume_id, row_id) as theid
      from resume
      where last_upd >= sysdate - 365
      group by coalesce(resume_id, row_id)
     ) rs left join
     resume r
     on rs.theid = r.id left join
     resume c
     on rs.theid = rs.resume_id;

答案 1 :(得分:0)

您可以简化查询,假设resume_id在主文档记录时为n​​ull。否则,请使用CASE表达式。

SELECT meta_data.row_id as "resume_id", 
       meta_data.name as "resume_name",
       components.name as "component_name"
FROM 
(
   SELECT DISTINCT coalesce(resume_id, row_id) row_id
   FROM  resume 
   WHERE last_upd > SYSDATE - 365
) updated_resumes
INNER JOIN resume meta_data ON updated_resumes.row_id = meta_data.row_id
LEFT JOIN resume components ON meta_data.row_id = components.resume_id

我不确定你为什么使用LEFT JOIN,根据需要进行调整。