2015-01-01 50 views
1

想象一個包含文檔的數據庫中的表 - 稱爲resume - 並且每個文檔都包含許多組件。在該表中的行可以是文檔本身(文檔的元數據),或該文件的部分:根據單行返回Oracle中的所有匹配行

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 

我想我的查詢工作,但如果它不「T或者如果還不清楚我想要做的,我的查詢應該返回:

resume_id resume_name component_name 
4   resume_2  
4   resume_2  section_1 
+1

您可能想考慮重命名您的列以指示父子關係? row_id可能會與Oracle rowid混淆。 – OldProgrammer

回答

0

可以簡化查詢,假設resume_id爲空時,它是主要的文件記錄。否則,使用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 

我不確定你爲什麼使用左連接,根據需要進行調整。

+0

我使用了左連接,因爲即使沒有組件行,簡歷元數據行也可以存在,並且我想確保我也抓住這些行。感謝您的幫助! – sepiroth

+0

好的,我已經調整了相應的查詢 – koriander

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; 
+0

我不認爲你寫的子查詢的作品 - 我粘貼它,改變我的變量,並得到'不是一個GROUP BY表達式'錯誤 – sepiroth

+0

@sepiroth。 。 。哎呀,那個'擁有'條款應該是'where'。 –

相關問題