Sybase SQL - удаление "полудубликатов" из результатов запроса
У меня есть запрос, который использует два SELECT
заявления, которые объединяются с использованием UNION ALL
, Оба оператора извлекают данные из одинаковых таблиц для заполнения результатов запроса. Я пытаюсь удалить "полудублированные" строки из запроса, но у меня возникают проблемы при этом.
Мой запрос следующий:
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).
Как я могу сделать так, чтобы каждому человеку отображалась только одна строка, используя критерии, которые я перечислил?
РЕДАКТИРОВАТЬ: изменил запрос SQL, чтобы показать оригинальные переменные из WHERE
пункты, чтобы показать более подробную информацию о запросе. Таблицы PatReimbursors и PatEligabilities имеют аналогичные данные, но критерии для получения правильных данных различны.
3 ответа
Ваш запрос не имеет смысла. Я бы начал с устранения неявного декартова произведения, генерируемого ,
в from
пункт.
Я предполагаю, что предложение 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
, Возможно, вы сможете указать как возмещение, так и право на участие в одном запросе.
Используйте подзапрос или подзапросы.
Общий запрос должен быть написан с использованием следующего шаблона:
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...]
Убедитесь, что условия исключают любую возможность для объединения генерировать более одной строки из другой [внешней] таблицы для каждой строки в таблице person. Это может (и часто делает) требовать, чтобы условие соединения основывалось на подзапросе, как, например,...
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)
Поработав с этим в течение некоторого времени сегодня, я нашел решение проблемы, с которой столкнулся. Вот решение, которое работает и извлекает нужную мне информацию:
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
Спасибо за все ответы, которые были предоставлены.