2015-03-24 2 views
0

У меня есть это SQLРегистрации другой таблицы с датой MAX

SELECT DISTINCT p.dbPatID, 
    p.dbpatfirstname, 
    p.dbPatLastName, 
    s.dbSchTypeCnt AS SchDetailType, 
    t.dbSchTypeCnt AS SchTypeType, 
    ISNULL(r.dbStatusDesc, 'No Ref') AS dbStatusDesc, 
    ISNULL(t.dbSchTypeCode, 'No Ref') AS dbSchTypeCode, 
    ISNULL(t.dbSchTypeDesc, 'No Ref') AS dbSchTypeDesc, 
    p.dbProgRvw, 
    ISNULL(s.dbSchDate, '1899-12-30') AS dbSchDate, 
    ISNULL(s.dbSchTypeCnt, '0') AS dbSchTypeCnt, 
    p.age, 
    ISNULL(rc.dbRecDate, '1899-12-30') AS dbRecDate, 
    ISNULL(rc.dbRecType, '-') AS dbRecType, 
    ISNULL(rc.dbRecCom, '-') AS dbRecCom, 
    a.dbPatApptTime AS LastVisitDate, 
    a.dbSchTypeDesc AS LastVisitDesc 
FROM Patient p 
LEFT JOIN vw_ReferralKPIs r 
    ON p.dbpatid = r.dbPatID 
     AND r.ClientRef = p.ClientRef 
LEFT JOIN SchDetail s 
    ON s.dbPatCnt = p.dbPatCnt 
     AND s.ClientRef = p.ClientRef 
LEFT JOIN SchTypes t 
    ON s.dbSchTypeCnt = t.dbSchTypeCnt 
     AND t.ClientRef = p.ClientRef 
LEFT JOIN Recalls rc 
    ON p.dbpatcnt = rc.dbpatcnt 
     AND rc.ClientRef = p.ClientRef 
LEFT JOIN Appointments a 
    ON p.dbpatcnt = a.dbpatcnt 
     AND rc.ClientRef = a.ClientRef 
     AND dbPFStatus = 1 
WHERE (
     r.dbStatusDesc IN ('') 
     OR '' = '' 
     ) 
    AND s.dbSchDate <= GetDate() 
    AND p.ClientRef = 'EPS' 
    AND r.dbStatusDesc != 'Discharged' 
    AND r.dbStatusDesc != 'TC Disch' 
    AND r.dbStatusDesc != 'Discharge FTA' 

Я добавил назначения присоединиться кодом, как нам нужно LastVisitDate и LastVisitDesc, но мы только хотим вернуть строку из Appointments, который имеет максимальную дату (последняя дата).

Если я добавлю временный пункт Where AND p.dbPatCnt = 9678, он возвращает 12 строк (все назначения этого человека, где dbPFStatus = 1). Я только хочу вернуть строку с последней датой.

I've found a similar problem/solution, но я не ясно о том, как применить его к моему коду

благодаря

Вслед за эту ссылку теперь у меня есть ...

SELECT DISTINCT 
     p.dbPatID, 
     p.dbpatfirstname, 
     p.dbPatLastName, 
     s.dbSchTypeCnt AS SchDetailType, 
     t.dbSchTypeCnt AS SchTypeType, 
     ISNULL(r.dbStatusDesc, 'No Ref') AS dbStatusDesc, 
     ISNULL(t.dbSchTypeCode, 'No Ref') AS dbSchTypeCode, 
     ISNULL(t.dbSchTypeDesc, 'No Ref') AS dbSchTypeDesc, 
     p.dbProgRvw, 
     ISNULL(s.dbSchDate, '1899-12-30') AS dbSchDate, 
     ISNULL(s.dbSchTypeCnt, '0') AS dbSchTypeCnt, 
     p.age, 
     ISNULL(rc.dbRecDate, '1899-12-30') AS dbRecDate, 
     ISNULL(rc.dbRecType, '-') AS dbRecType, 
     ISNULL(rc.dbRecCom, '-') AS dbRecCom, 
     -- New columns 
     ca.LastVisitDate, 
     ca.LastVisitDesc 
FROM Patient p 
LEFT OUTER JOIN vw_ReferralKPIs r ON p.dbpatid = r.dbPatID 
            AND r.ClientRef = p.ClientRef 
LEFT OUTER JOIN SchDetail s ON s.dbPatCnt = p.dbPatCnt 
           AND s.ClientRef = p.ClientRef 
LEFT OUTER JOIN SchTypes t ON s.dbSchTypeCnt = t.dbSchTypeCnt 
           AND t.ClientRef = p.ClientRef 
LEFT OUTER JOIN Recalls rc ON p.dbpatcnt = rc.dbpatcnt 
           AND rc.ClientRef = p.ClientRef 
LEFT OUTER JOIN (SELECT MAX(a.dbPatApptTime) AS LastVisitDate, 
          MAX(a.dbSchTypeDesc) AS LastVisitDesc, 
          a.dbpatcnt 
        FROM  appointments a 
        WHERE  a.dbPFStatus = 1 
          AND a.clientref = 'EPS' 
        GROUP BY a.dbpatcnt 
       ) ca ON ca.dbpatcnt = p.dbpatcnt 
WHERE --(
      --r.dbStatusDesc IN ('') 
      --OR '' = '' 
     --) AND 
     s.dbSchDate <= GETDATE() 
     AND p.ClientRef = 'EPS' 
     AND r.dbStatusDesc != 'Discharged' 
     AND r.dbStatusDesc != 'TC Disch' 
     AND r.dbStatusDesc != 'Discharge FTA'; 

Это возвращает ожидаемое количество строк и исправить LastVisitDate, но LastVistDesc ошибочен. Я пробовал его без Max и включил его в Group By, но это создает много повторяющихся строк.

спасибо,

+0

Какая версия сервера SQL вы используете? – JNevill

+0

Имея основные справочные таблицы WHERE, которые находятся в LEFT OUTER JOIN, заставляет их стать INNER JOIN. Таким образом, либо вы хотите LEFT OUTER JOIN, переместите главную, где клаузулы, в отдельные предложения JOIN, либо измените LEFT OUTER на INNER. Это увеличит производительность. Другим комментарием является GROUP BY, что вы также будете вызывать проблемы с производительностью, просто FYI – Dbloch

ответ

0

Попробуйте это:

SELECT DISTINCT p.dbPatID, 
    p.dbpatfirstname, 
    p.dbPatLastName, 
    s.dbSchTypeCnt AS SchDetailType, 
    t.dbSchTypeCnt AS SchTypeType, 
    ISNULL(r.dbStatusDesc, 'No Ref') AS dbStatusDesc, 
    ISNULL(t.dbSchTypeCode, 'No Ref') AS dbSchTypeCode, 
    ISNULL(t.dbSchTypeDesc, 'No Ref') AS dbSchTypeDesc, 
    p.dbProgRvw, 
    ISNULL(s.dbSchDate, '1899-12-30') AS dbSchDate, 
    ISNULL(s.dbSchTypeCnt, '0') AS dbSchTypeCnt, 
    p.age, 
    ISNULL(rc.dbRecDate, '1899-12-30') AS dbRecDate, 
    ISNULL(rc.dbRecType, '-') AS dbRecType, 
    ISNULL(rc.dbRecCom, '-') AS dbRecCom, 
    a.dbPatApptTime AS LastVisitDate, 
    a.dbSchTypeDesc AS LastVisitDesc 
FROM Patient p 
LEFT JOIN vw_ReferralKPIs r 
ON p.dbpatid = r.dbPatID 
    AND r.ClientRef = p.ClientRef 
LEFT JOIN SchDetail s 
ON s.dbPatCnt = p.dbPatCnt 
    AND s.ClientRef = p.ClientRef 
LEFT JOIN SchTypes t 
ON s.dbSchTypeCnt = t.dbSchTypeCnt 
    AND t.ClientRef = p.ClientRef 
LEFT JOIN Recalls rc 
ON p.dbpatcnt = rc.dbpatcnt 
    AND rc.ClientRef = p.ClientRef 
LEFT JOIN Appointments a 
ON p.dbpatcnt = a.dbpatcnt 
    AND rc.ClientRef = a.ClientRef 
    AND dbPFStatus = 1 
WHERE (
    r.dbStatusDesc IN ('') 
    OR '' = '' 
    ) 
AND s.dbSchDate <= GetDate() 
AND p.ClientRef = 'EPS' 
AND r.dbStatusDesc != 'Discharged' 
AND r.dbStatusDesc != 'TC Disch' 
AND r.dbStatusDesc != 'Discharge FTA' 
AND a.dbPatApptTime = (SELECT MAX(a2.dbPatApptTime) 
    FROM Appointment a2 
    WHERE a2.ClientRef = a.ClientRef 
    AND a2.dbPFStatus = 1) 
+0

Это сломает LEFT JOIN в таблице назначения, поэтому его нужно будет вывести из основного предложения WHERE и в предложение JOIN – Dbloch

0

Было бы лучше, чтобы написать функцию Table-значение, которое будет возвращать данные с входными параметрами ClientRef и dbpacnt. Затем вы можете включить функцию в оператор select.

CREATE FUNCTION [dbo].[LastAppointment] 
    (@clientRef INT, 
     @dbpatcnt INT 
    ) 
RETURNS TABLE 
AS 
RETURN 
    (SELECT TOP 1 
       a.dbPatApptTime AS LastVisitDate, 
       a.dbSchTypeDesc AS LastVisitDesc 
     FROM  Appointments a 
     WHERE  ClientRef = @clientRef 
       AND Dbpatcnt = @dbpatcnt 
       AND dbPFStatus = 1 
     ORDER BY a.dbPatApptTime) 

GO 

Затем измените

LEFT JOIN Recalls rc 
    ON p.dbpatcnt = rc.dbpatcnt 
     AND rc.ClientRef = p.ClientRef 
LEFT JOIN Appointments a 
    ON p.dbpatcnt = a.dbpatcnt 
     AND rc.ClientRef = a.ClientRef 
     AND dbPFStatus = 1 

Для

LEFT JOIN Recalls rc 
    ON p.dbpatcnt = rc.dbpatcnt 
     AND rc.ClientRef = p.ClientRef 
CROSS APPLY dbo.LastAppointment (rc.ClientRef, p.dbpatcnt) 
Смежные вопросы