我怎样才能更好地编写这个SQL?

时间:2009-07-16 03:30:26

标签: sql sql-server

我有患者,服务,患者状态,状态表 - 患者可以通过服务区分多种状态。

我想构建一个视图,显示每个服务和每个患者的当前状态,即使他们没有该服务的状态。

我有一些SQL可以做到这一点,但我能写得更好吗? (我主要关注1 = 1的患者的内部联接)

这是SQL:

select
    p.Code,
    s.pkServiceId, 
    ps.fkPatientId, 
    ps.fkStatusId, 
    s.Code AS ServiceCode, 
    s.Description AS ServiceDescription, 
    st.Code AS StatusCode, 
    st.Description as StatusDescription, 
    ps.TsStart
from 
    Service s
inner join
    Patient p on 1 = 1
left outer join
      (select
            max(TsStart) AS TsStart, 
            fkPatientId, 
            fkServiceId
        from
            PatientStatus AS ps
        group by
            fkServiceId, fkPatientId
     ) AS psLast on 
        psLast.fkServiceId = s.pkServiceId and 
        psLast.fkPatientId = p.pkPatientId
left outer join
    PatientStatus AS ps ON 
        psLast.TsStart = ps.TsStart and 
        psLast.fkPatientId = ps.fkPatientId and 
        psLast.fkServiceId = ps.fkServiceId 
left outer join
    Status st on
        st.pkStatusId = ps.fkStatusId

3 个答案:

答案 0 :(得分:4)

Duh ...我的1 = 1与将其重写为CROSS JOIN相同:

这     服务 交叉加入     病人p

答案 1 :(得分:1)

如果他们没有该服务的状态,您是否需要显示患者/服务的行?看起来这应该是我在前端处理的事情。

那说,为了得到你想要的东西,我可能会使用以下内容:

SELECT
    P.Code,
    S.pkServiceID,  --Ugh, I hate that naming convention
    PS.fkPatientID,
    PS.fkStatusID,
    S.Code AS ServiceCode,
    S.Description AS ServiceDescription,
    ST.Code AS StatusCode,
    ST.Description AS StatusDescription
    PS.TsStart
FROM
    Patient P
CROSS JOIN Service S
LEFT OUTER JOIN PatientStatus PS ON
    PS.fkPatientID = P.pkPatientID AND
    PS.fkServiceID = S.pkServiceID
LEFT OUTER JOIN PatientStatusPS2 ON
    PS2.fkPatientID = P.pkPatientID AND
    PS2.fkServiceID = S.pkServiceID AND
    PS2.TsStart > PS.TsStart
LEFT OUTER JOIN Status ST ON
    ST.pkStatusID = PS.fkStatusID
WHERE
    PS2.fkPatientID IS NULL

快速说明一下......如果你有两种状态与同一患者和服务的完全相同的TsStart,那么你将在这里获得重复。您也可以从原始查询中获取这些内容。如果需要,您可以编写代码。只需将PS2上的联接中的最后一行更改为:

(PS2.TsStart > PS.TsStart OR (PS2.TsStart = PS.TsStart AND PS2.pkID > PS.pkID))

答案 2 :(得分:0)

我想知道为什么患者和服务表之间没有关系?为什么要使用“1 = 1”?

假设患者服务是多对多的关系 ...     服务 内部联接      (PatientService ps inner join p ps.PCode = p.Code上的患者p)         在s.Code = ps.SCode上 ...