在TSQL中选择selfjoin中的第一个子记录

在TSQL中选择selfjoin中的第一个子记录,tsql,join,subquery,Tsql,Join,Subquery,我有一张表,看起来像这样: id identity(1,1) not null, visit_date datetime not null, patient_id int not null, flag bit not null 对于每个记录,我需要找到一个相同时间或更早的匹配记录,具有相同的患者id,并且标志设置为1。我现在做的是: select parent.id as parent_id, ( select top 1 child.id as child_id

我有一张表,看起来像这样:

id identity(1,1) not null,
visit_date datetime not null,
patient_id int not null,
flag bit not null
对于每个记录,我需要找到一个相同时间或更早的匹配记录,具有相同的患者id,并且标志设置为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

因此,这个查询工作正常,只是运行太慢——我怀疑这是因为子查询。是否可以将其重写为联接查询?

查看查询执行计划。如果你有粗箭头,看看那些陈述。您应该了解不同的语句及其含义,如什么是聚集索引扫描/搜索等

通常当查询速度变慢时,我发现没有好的索引

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

   /* 
    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