2012-02-24 53 views
0

一個selfjoin我有一個visits表看起來像這樣:選擇的第一個孩子記錄在TSQL

id identity(1,1) not null, 
visit_date datetime not null, 
patient_id int not null, 
flag bit not null 

對於每一個記錄,我需要找到一個匹配的記錄是同時或更早,具有相同的patient_id,並具有flag設置爲1。我現在正在做的是:

select parent.id as parent_id, 
(
    select top 1 
     child.id as child_id 
    from 
     visits as child 
    where 
    child.visit_date <= parent.visit_date 
    and child.patient_id = parent.patient_id 
    and child.flag = 1 
    order by 
    visit_date desc 
) as child_id 
from 
    visits as parent 

所以,此查詢工作正常,但它運行太慢了 - 我懷疑這是因爲子查詢。是否有可能將其重寫爲聯接查詢?

回答

0
/* 
    id identity(1,1) not null, 
    visit_date datetime not null, 
    patient_id int not null, 
    flag bit not null 
    */ 

SELECT 
    T.parentId, 
    T.patientId, 
    V.id AS childId 
FROM 
    (
    SELECT 
     visit.id AS parentId, 
     visit.patient_id AS patientId, 
     MAX (previous_visit.visit_date) previousVisitDate 
    FROM 
     visit 
     LEFT JOIN visit previousVisit ON 
      visit.patient_id = previousVisit.patient_id 
      AND visit.visit_date >= previousVisit.visit_date 
      AND visit.id <> previousVisit.id 
      AND previousVisit.flag = 1 
    GROUP BY 
     visit.id, 
     visit.visit_date, 
     visit.patient_id, 
     visit.flag 
    ) AS T 
    LEFT JOIN visit V ON 
     T.patientId = V.patient_id 
     AND T.previousVisitDate = V.visit_date 
1

查看查詢執行計劃。如果你有粗箭頭,看看這些陳述。你應該學習不同的語句以及它們暗示的內容,比如聚簇索引掃描/尋找等。

通常當查詢進行得很慢時,我發現沒有好的索引。

受影響並用於連接的表和列,創建一個涵蓋所有這些列的索引。這通常在論壇中被稱爲覆蓋指數。這是你可以爲真正需要的東西做的事情。但請記住,太多索引會減慢插入語句的速度。

相關問題