连接多个表导致重复的行

时间:2018-08-30 05:42:53

标签: sql sql-server sql-server-2008 sql-server-2012

有些拖车表(客户和反馈)具有不同的信息。以下查询几乎是正确的,除了它导致重复的行。我只需要唯一的行作为客户id即可,对于空值则不需要。

我在最后尝试了GROUP BY子句,但它给出了错误。

Select C.CustomerId, 
       C.FirstName, 
       C.LastName, 
       (SELECT CAST(CASE WHEN F.Id != null or F.Type = 'Query' 
                         THEN 'YES' ELSE 'NO' END AS NVARCHAR(50))) as Query,
       (SELECT CAST(CASE WHEN F.Id != null or F.Type = 'Feedback' 
                         THEN 'YES' ELSE 'NO' END AS NVARCHAR(50))) as Feedback
FROM Customer C
LEFT JOIN Feedback F on  F.CustomerId= C.CustomerId

enter image description here

Select * from Customer

enter image description here

Select * from Feedback

enter image description here

作为结果,我只想按customerId显示单个行,并加入如​​下所示的反馈表数据... enter image description here

5 个答案:

答案 0 :(得分:2)

您可以尝试以下任一方法

SELECT
    C.*,
    Query = CASE WHEN PVT.Query IS NOT NULL THEN 'Yes' ELSE 'No' END,
    Feedback = CASE WHEN PVT.Feedback IS NOT NULL THEN 'Yes' ELSE 'No' END
    FROM Customer C
        LEFT JOIN  FeedBack
            PIVOT
            (
                MAX(Id)
                FOR
                [Type] IN
                (
                    [Query],[Feedback]
                )
            )Pvt
            ON PVT.CustomerId = c.CustomerId

或简单地

SELECT
    C.*,
    Query = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='Query') THEN 'Yes' ELSE 'No' END,
    Feedback = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='Feedback') THEN 'Yes' ELSE 'No' END
    FROM Customer C

要使其更具动态性,您可以尝试

DECLARE @SQL VARCHAR(MAX)

;WITH CTE
AS
(
    SELECT
        RN = ROW_NUMBER() OVER(PARTITION BY [Type] ORDER BY [Type]),
        QRY = LTRIM(RTRIM([Type]))+' = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='''+LTRIM(RTRIM([Type]))+''') THEN ''Yes'' ELSE ''No'' END'
        FROM FeedBack
)
SELECT
    @SQL = 'SELECT
    C.*'
    +SUBSTRING(','+L.List,1,LEN(L.List)-1)
    +' FROM Customer C'
    FROM 
    (
        SELECT
            QRY + ', ' [text()]
            FROM CTE
                WHERE RN = 1
                FOR XML PATH('')
    )L(List)

EXEC(@SQL)

有关详细示例,请参阅此Sqlfiddle

答案 1 :(得分:1)

Select C.CustomerId, 
       C.FirstName, 
       C.LastName, 
       sum(case when F.Type = 'Query' then 1 else 0 end) > 0 as Query,
       sum(case when F.Type = 'Feedback' then 1 else 0 end) > 0 as Feedback
FROM Customer C
LEFT JOIN Feedback F on  F.CustomerId= C.CustomerId
GROUP BY C.CustomerId, C.FirstName, C.LastName

答案 2 :(得分:0)

使用子查询尝试以下查询:

    select *,case when query=1 then 'Yes' else 'No' end as query, 
case when feedback=1 then 'Yes' else 'No' end as feedbackfrom
(select CustomerId, firstname,lastname,
        sum(CASE WHEN Type = 'Query' 
             THEN 1 ELSE 0 END) as Query,

        sum(CASE WHEN Type = 'Feedback' 
             THEN 1 ELSE 0 END)  as Feedback from Customer C
        LEFT JOIN Feedback F on  F.CustomerId= C.CustomerId
group by CustomerId, firstname,lastname)a

答案 3 :(得分:0)

使用case when

Select C.CustomerId, 
       C.FirstName, 
       C.LastName, 
       case when sum(case when F.Type = 'Query' then 1 else 0 end) > 0  then 'Yes' else 'NO' end as Query,
    case when   sum(case when F.Type = 'Feedback' then 1 else 0 end) > 0 then 'Yes' else 'NO' End as Feedback
FROM Customer C
LEFT JOIN Feedback F on  F.CustomerId= C.CustomerId
GROUP BY C.CustomerId, C.FirstName, C.LastName

答案 4 :(得分:0)

尝试一下:

select c.CustomerId,
       c.FirstName,
       c.LastName,
       case when q.CustomerId is null then 'NO' else 'YES' end Query,
       case when f.CustomerId is null then 'NO' else 'YES' end Feedback,
from Customers c
left join (select customerId from Feedback where Type = 'Query' ) q on c.CustomerId = q.CustomerId
left join (select customerId from Feedback where Type = 'Feedback' ) f on c.CustomerId = q.CustomerId