2012-02-24 62 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

查看查询执行计划。如果你有粗箭头,看看这些陈述。你应该学习不同的语句以及它们暗示的内容,比如聚簇索引扫描/寻找等。

通常当查询进行得很慢时,我发现没有好的索引。

受影响并用于连接的表和列,创建一个涵盖所有这些列的索引。这通常在论坛中被称为覆盖指数。这是你可以为真正需要的东西做的事情。但请记住,太多索引会减慢插入语句的速度。