2013-03-21 6 views
0

У меня есть запрос, который использует два оператора SELECT, которые объединены с помощью UNION ALL. Оба оператора извлекают данные из аналогичных таблиц для заполнения результатов запроса. Я пытаюсь удалить «полудубличные» строки из запроса, но у меня возникают проблемы с этим.Sybase SQL - Удалить «полу-дубликаты» из результатов запроса

Мой запрос состоит в следующем:

SELECT DISTINCT * 
FROM 
    (
    SELECT 
     TeamNum = CASE 
       WHEN T.TeamName = 'Alpha Team' 
        THEN '1' 
       WHEN T.TeamName IN ('Bravo Team', 'Charlie Team') 
        THEN '2' 
       WHEN T.TeamName = 'Delta Team' 
        THEN '3' 
       ELSE '<Undefined>' 
       END, 
     P.PatientLastName AS LastName, 
     P.PatientFirstName AS FirstName, 
     R.PrimaryCity AS City, 
     ReimbursorName = CASE 
       WHEN RE.ReimbursorDescription = 'Medicare' 
        Then 'R1' 
       WHEN RE.ReimbursorDescription = 'Medicaid' 
        Then 'R2' 
       ELSE 'R3' 
       END, 
     P.PatientID AS PatientID 
    FROM 
     PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID, 
     Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID, 
     PatReferrals PR LEFT OUTER JOIN PatReimbursors PRE ON PR.PatientID = PRE.PatientID, 
     PatReimbursors PRE LEFT OUTER JOIN Reimbursors RE ON PRE.ReimbursorID = RE.ReimbursorID, 
     PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID, 
    WHERE 
     PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1 
     AND PR.Status <> 'R' 
     AND PRE.CoveragePriority = '1' 
     AND PRE.ExpirationDate IS NULL 

    UNION ALL 

    SELECT 
     TeamNum = CASE 
       WHEN T.TeamName = 'Alpha Team' 
        THEN '1' 
       WHEN T.TeamName IN ('Bravo Team', 'Charlie Team') 
        THEN '2' 
       WHEN T.TeamName = 'Delta Team' 
        THEN '3' 
       ELSE '<Undefined>' 
       END, 
     P.PatientLastName AS LastName, 
     P.PatientFirstName AS FirstName, 
     R.PrimaryCity AS City, 
     ReimbursorName = CASE 
       WHEN RE.ReimbursorDescription = 'Medicare' 
        Then 'E1' 
       WHEN RE.ReimbursorDescription = 'Medicaid' 
        Then 'E2' 
       ELSE 'E3' 
       END, 
     P.PatientID AS PatientID 
    FROM 
     PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID, 
     Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID, 
     PatReferrals PR LEFT OUTER JOIN PatEligibilities PE ON PR.PatientID = PE.PatientID, 
     PatEligibilities PE LEFT OUTER JOIN Reimbursors RE ON PE.ReimbursorID = RE.ReimbursorID, 
     PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID, 
    WHERE 
     PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1 
     AND PR.Status <> 'R' 
     AND PE.Status <> 'V' 
     AND PE.ApplicationDate BETWEEN DATE(PR.ReferralDate)-5 AND DATE('2100/01/01') 
    ) 

AS DUMMYTBL 

ORDER BY 
    DUMMYTBL.LastName ASC, 
    DUMMYTBL.FirstName ASC 

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

3 Doe Jane Town R1 19874 
1 Roe John City R3 50016 
1 Roe John City E1 50016 
2 Smith Jane Town E3 33975 

Данные, которые я нуждаясь удалить, повторяющиеся строки на основе по определенным критериям, как только результаты будут получены из исходного запроса. Каждый человек может быть указан только один раз, и у них должен быть один источник оплаты (R1, R2, R3, E1, E2, E3). Если есть R #, то для этого человека не может быть E #. Если нет R #, то необходимо указать E #. Как показано в моих примерах, строки 2 и 3 имеют один и тот же список, но два источника оплаты (R3 и E1).

Как я могу заставить каждого человека показывать только одну строку, используя критерии, которые я перечислял?

EDIT: Изменен SQL-запрос, чтобы показать исходные переменные из предложений WHERE, чтобы показать дополнительную информацию о запросе. Таблицы PatReimbursors и PatEligibilities имеют аналогичные данные, но критерии различаются, чтобы вытащить правильные данные.

+0

'TeamNum = T.TeamName,'? Это опечатка? – Rachcha

+0

Действительно ли это рабочий запрос? Выражения 'from', как представляется, имеют множественные вхождения одних и тех же псевдонимов - похоже, что это никогда не будет работать. Кроме того, если есть несколько источников «R», которые должны иметь приоритет? –

+0

@ Rachcha - Я сократил эту часть запроса, поскольку он первоначально был оператором 'CASE', чтобы возвращать числа из' TeamName'. @Mark Bannister - Да, этот запрос действительно работает. –

ответ

2

Ваш запрос не имеет смысла. Я бы начал с устранения неявного декартова продукта, сгенерированного , в предложении from.

Я думаю, что из пункта должно быть:

FROM 
    PatReferrals PR LEFT JOIN 
    Patient P 
    ON PR.PatientID = P.PatientID left outer join 
    Rolodex R 
    ON P.RolodexID = R.RolodexID left outer join 
    PatEligibilities PE 
    ON PR.PatientID = PE.PatientID left outer join 
    Reimbursors RE 
    ON PE.ReimbursorID = RE.ReimbursorID left outer join 
    Teams T ON PR.TeamID = T.TeamID 

После того, как вы сделаете это, вы не можете нуждаться в union all или select distinct. Возможно, вы сможете разместить как компенсаторы, так и права на участие в одном и том же запросе.

+0

Таблица PatReferrals разворачивается как для PatReimbursors, так и для PatEligibilities. Чтобы получить оба значения для заполнения в одном запросе, необходимо было установить «UNION» из двух аналогичных операторов SELECT. Без этого я бы либо получил данные от PatReimbursors или PatEligibilities, но не обоих. –

+0

Все в порядке. Это предотвращает один тип декартова продукта. Однако вы ввели несколько других, включив в предложение 'from' '. –

1

Использовать подзапрос или подзапросы.

Общий запрос должен быть написано с использованием следующей схемы:

Select Distinct [Person Data] 
From PersonTable 
    left Join to otherTable1 -- add outer join for each table you need data from 
     On [Conditions that ensure join can generate only one row per person, 
       ... and specify which of possibly many rows to get...] 

Убедитесь, что условия исключить любую возможность для объединения для создания более одной строки из других [внешних] таблиц на человек строку в человек таблица ,. Это может быть (и часто бывает) требует, чтобы условия объединения основывается на подзапрос, как, например ...

Select Distinct [Person Data] 
From PersonTable p 
    left Join to employments e -- add outer join for each table you need data from 
     On e.PersonId = p.PersonId 
      and e.HireDate = (Select Max(hiredate) from employments 
           where personId = p.PersonId) 
0

После работы с этим в течение некоторого времени сегодня, я нашел решение проблемы, Я имел. Вот решение, которое работает и достает правильную информацию, которая мне нужна:

SELECT DISTINCT 
    TeamNum, 
    LastName, 
    FirstName, 
    City, 
    ReimbursorName = CASE 
     WHEN max(ReimbursorName) IN ('R1', 'E1') 
      THEN '1' 
     WHEN max(ReimbursorName) IN ('R2', 'E2') 
      THEN '2' 
     ELSE '3' 
     END, 
    PatientID 
FROM 
    (
    SELECT 
     TeamNum = CASE 
       WHEN T.TeamName = 'Alpha Team' 
        THEN '1' 
       WHEN T.TeamName IN ('Bravo Team', 'Charlie Team') 
        THEN '2' 
       WHEN T.TeamName = 'Delta Team' 
        THEN '3' 
       ELSE '<Undefined>' 
       END, 
     P.PatientLastName AS LastName, 
     P.PatientFirstName AS FirstName, 
     R.PrimaryCity AS City, 
     ReimbursorName = CASE 
       WHEN RE.ReimbursorDescription = 'Medicare' 
        Then 'R1' 
       WHEN RE.ReimbursorDescription = 'Medicaid' 
        Then 'R2' 
       ELSE 'R3' 
       END, 
     P.PatientID AS PatientID 
    FROM 
     PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID, 
     Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID, 
     PatReferrals PR LEFT OUTER JOIN PatReimbursors PRE ON PR.PatientID = PRE.PatientID, 
     PatReimbursors PRE LEFT OUTER JOIN Reimbursors RE ON PRE.ReimbursorID = RE.ReimbursorID, 
     PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID 
    WHERE 
     PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1 
     AND PR.Status <> 'R' 
     AND PRE.CoveragePriority = '1' 
     AND PRE.ExpirationDate IS NULL 

    UNION ALL 

    SELECT 
     TeamNum = CASE 
       WHEN T.TeamName = 'Alpha Team' 
        THEN '1' 
       WHEN T.TeamName IN ('Bravo Team', 'Charlie Team') 
        THEN '2' 
       WHEN T.TeamName = 'Delta Team' 
        THEN '3' 
       ELSE '<Undefined>' 
       END, 
     P.PatientLastName AS LastName, 
     P.PatientFirstName AS FirstName, 
     R.PrimaryCity AS City, 
     ReimbursorName = CASE 
       WHEN RE.ReimbursorDescription = 'Medicare' 
        Then 'E1' 
       WHEN RE.ReimbursorDescription = 'Medicaid' 
        Then 'E2' 
       ELSE 'E3' 
       END, 
     P.PatientID AS PatientID 
    FROM 
     PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID, 
     Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID, 
     PatReferrals PR LEFT OUTER JOIN PatEligibilities PE ON PR.PatientID = PE.PatientID, 
     PatEligibilities PE LEFT OUTER JOIN Reimbursors RE ON PE.ReimbursorID = RE.ReimbursorID, 
     PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID 
    WHERE 
     PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1 
     AND PR.Status <> 'R' 
     AND PE.Status <> 'V' 
     AND PE.ApplicationDate BETWEEN DATE(PR.ReferralDate)-5 AND DATE('2100/01/01') 
    ) 

AS DUMMYTBL 
GROUP BY 
    TeamNum, 
    LastName, 
    FirstName, 
    City, 
    PatientID 
ORDER BY 
    DUMMYTBL.LastName ASC, 
    DUMMYTBL.FirstName ASC 

Спасибо за все ответы, которые были предоставлены.

 Смежные вопросы

  • Нет связанных вопросов^_^