2013-03-21 55 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)。

我怎樣才能讓每個人只有一行顯示使用我列出的標準?

編輯:修改SQL查詢以顯示WHERE子句中的原始變量,以顯示查詢的更多詳細信息。 PatReimbursors和PatEligibilities表具有相似的數據,但標準不同以便提取正確的數據。

+0

'TeamNum = T.TeamName,'?這是一個錯字嗎? – Rachcha 2013-03-21 15:55:59

+0

這是一個真正的查詢嗎? 'from'子句似乎有多個相同別名的出現 - 看起來好像它永遠不會運行。另外,如果有多個「R」來源,哪個要優先? – 2013-03-21 15:59:46

+0

@Rachcha - 我縮短了查詢的部分內容,因爲它最初是一個'CASE'語句,可以從'TeamName'返回數字。 @Mark Ba​​nnister - 是的,這個查詢確實有效。 – 2013-03-21 16:00:01

回答

2

您的查詢沒有意義。我將首先消除條款中產生的隱式笛卡爾積。

我的猜測是,從條款應該是:

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 allselect distinct。您可能能夠同時查詢報銷員和資格。

+0

PatReferrals表分派給PatReimbursors和PatEligibilities。爲了讓兩個值填充到同一個查詢中,必須插入兩個相似'SELECT'語句的'UNION'。沒有這些,我會從PatReimbursors或PatEligibilities獲取數據,但不是兩者。 – 2013-03-21 17:30:06

+0

這很好。這阻止了一種類型的笛卡爾產品。但是,通過在'from'子句中包含「,」來引入多個其他人。 – 2013-03-21 17:32:41

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 

感謝您提供的所有答覆。