Как я могу написать этот SQL лучше? - PullRequest
0 голосов
/ 16 июля 2009

У меня есть таблицы Patient, Service, PatientStatus, Status - у пациента может быть несколько статусов, различаемых службой.

Я хочу создать представление, которое показывает для каждого сервиса и каждого пациента, каково их текущее состояние, даже если у них нет статуса для этой услуги.

У меня есть некоторый 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 ]

4 голосов
/ 16 июля 2009

Да ... мой 1 = 1 - это то же самое, что переписать его как CROSS JOIN:

из Сервисы перекрестное соединение Пациент р

1 голос
/ 16 июля 2009

Есть ли причина, по которой вам нужно, чтобы строки отображались для пациента / служб, если у них нет статуса для этой службы? Похоже, что это должно быть что-то обработано на переднем конце для меня.

Тем не менее, чтобы получить то, что вы ищете, я бы, вероятно, использовал следующее:

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))
0 голосов
/ 16 июля 2009

Я удивился, почему нет связи между таблицей пациента и службой? Почему следует использовать «1 = 1»?

Предполагая, что «Пациент-Сервис» - это связь между многими ... Сервисы внутреннее соединение (PatientService ps внутреннее соединение Patient p на ps.PCode = p.Code) на s.Code = ps.SCode ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...