Sybase SQL - 从查询结果中删除“半重复”

时间:2013-03-21 15:50:04

标签: sql sybase duplicate-removal sybase-asa

我有一个查询,它使用两个使用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和PatEligibilities表有类似的数据,但标准是不同的,以便提取正确的数据。

3 个答案:

答案 0 :(得分:2)

您的查询没有意义。我首先要删除由,子句中的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 allselect distinct。您可以将报销者和资格同时放在同一个查询中。

答案 1 :(得分: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...]

确保条件消除了联接从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)

答案 2 :(得分: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

感谢您提供的所有回复。