简体   繁体   中英

Trying to combine multiples of a key ID into single row, but with different values in columns

TSQL - SQL Sever

I'm building a report to very specific requirements. I'm trying to combine multiples of a key ID into single rows, but there's different values in some of the columns, so GROUP BY won't work.

SELECT count(tt.Person_ID) as CandCount, tt.Person_ID, 
CASE e.EthnicSuperCategoryID WHEN CandCount > 1 THEN 10 ELSE e.EthnicSuperCategoryID END as EthnicSuperCategoryID,
CASE e.Ethnicity_Id WHEN 1 THEN 1 ELSE 0 END as Black ,
CASE e.Ethnicity_Id WHEN 2 THEN 1 ELSE 0 END as White ,
CASE e.Ethnicity_Id WHEN 3 THEN 1 ELSE 0 END as Asian,
etc
FROM T_1 TT
JOINS
WHERE
GROUP

Msg 102, Level 15, State 1, Line 4 Incorrect syntax near '>'.

Here's the results (without the first CASE). Note person 3 stated multiple ethnicities.

SELECT count(tt.Person_ID) as CandCount, tt.Person_ID, 
CASE e.Ethnicity_Id WHEN 1 THEN 1 ELSE 0 END as Black ,
CASE e.Ethnicity_Id WHEN 2 THEN 1 ELSE 0 END as White ,
CASE e.Ethnicity_Id WHEN 3 THEN 1 ELSE 0 END as Asian,
etc
FROM T_1 TT
JOINS
WHERE
GROUP

结果

That's expected, but the goal would be to assign multiple ethnicities to Ethnicity_Id of 10 (multiple). I also want them grouped on a single line.

So the end result would look like this:

期望的结果

So my issue is two fold. If the candidate has more than 2 ethnicities, assign the records to Ethnicity_Id of 10. I also need duplicated person IDs grouped into a single row, while displaying all of the results of the columns.

This should bring your desired result:

SELECT Person_ID
     , ISNULL(ID_Dummy,Ethnicity_ID) Ethnicity_ID
     , MAX(Black) Black
     , MAX(White) White
     , MAX(Asian) Asian
  FROM @T T
 OUTER APPLY(SELECT MAX(10) FROM @T T2 
               WHERE T2.Person_ID = T.Person_ID 
                 AND T2.Ethnicity_ID <> T.Ethnicity_ID
            )EthnicityOverride(ID_Dummy)
 GROUP BY Person_ID, ISNULL(ID_Dummy,Ethnicity_ID)

You want conditional aggregation. Your query is incomplete, but the idea is:

select 
    person_id, 
    sum(case ethnicity_id = 1 then 1 else 0 end) as black,
    sum(case ethnicity_id = 2 then 1 else 0 end) as white,
    sum(case ethnicity_id = 3 then 1 else 0 end) as asian
from ...
where ...
group by person_id

You might want max() instead of sum() . Also I did not get the logic for column the second column in the desired results - maybe that's just count(*) .

This would be my approach

SELECT 
    person_id,
    CASE WHEN flag = 1 THEN Ethnicity_Id ELSE 10 END AS Ethnicity_Id,
    [1] as black,
    [2] as white,
    [3] as asian
FROM  
(
    SELECT 
        person_id, 
        Ethnicity_Id as columns,
        1 as n,
        MAX(Ethnicity_Id) over(PARTITION BY person_id) as Ethnicity_Id,
        COUNT(Ethnicity_Id) over(PARTITION BY person_id) as flag
    FROM 
        #example
) AS SourceTable  
PIVOT  
(  
    MAX(n) FOR columns IN ([1], [2], [3])  
) AS PivotTable;
  • Pivot the Ethnicity_Id column into multiples columns, Using constant 1 to make it complain with your expected result.
  • Using Max(Ethnicity_Id) with Partition By to get the original Ethnicity_Id
  • Using Count(Ethnicity_Id) to flag if a need to raplace Ethnicity_Id
    with 10 bc there is more that 1 row for that person_id

If you need to add more Ethnicitys add the ids in ... IN ([1], [2], [3])... and in the select

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM