0

Need a simple help here. Have went though various solutions such as using case and row number, pivot but unable to find a suitable solution.

Basically I want to use the group the Name values and find all the non null and distinct value and display the results in a single row.

Input

Name | Color
John | Blue
John | Green
Mary | NULL
Mary | Yellow
Mary | Pink
Mary | Pink

Expected Output

Name | Color1 | Color2 | Color3
John | Blue   | Green  |  NULL
Mary | Yellow | Pink   |  NULL

Currently I've came up to the query below but still looks far from my desired outcome. Appreciate your assistance , thanks!

select  Name,
    max(case when seqnum = 1 then Color end) as Color1,
    max(case when seqnum = 2 then Color end) as Color2,
    max(case when seqnum = 3 then Color end) as Color3
from (select table.*, row_number() over (partition by Name order by Name) as seqnum
    from table
    ) table
group by Name
2
  • Which dbms are you using? Commented Oct 30, 2018 at 6:51
  • Using SQL server Commented Oct 30, 2018 at 7:06

2 Answers 2

2

I think you should be using DENSE_RANK here, rather than ROW_NUMBER:

SELECT
    Name,
    MAX(CASE WHEN rnk = 1 THEN Color END) AS Color1,
    MAX(CASE WHEN rnk = 2 THEN Color END) AS Color2,
    MAX(CASE WHEN rnk = 3 THEN Color END) AS Color3
FROM
(
    SELECT *, DENSE_RANK() OVER (PARTITION BY Name
        ORDER BY CASE WHEN Color IS NOT NULL THEN 0 ELSE 1 END, Color) rnk
    FROM yourTable
) t
GROUP BY
    Name;

enter image description here

Demo

It isn't entirely clear what ordering you actually want to use for the colors, since in your expected output John's color are ascending while Mary's are descending. I chose to order ascending, with NULLs last.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I kind of understand the concept now. Issue is because the table is joined with multiple tables, currently figuring out how to include the join statements
0

You could get the result as json like in the example:

SELECT concat(
    '{',
    name,
    ':[',
    GROUP_CONCAT(color),
    ']}'
) FROM `test` GROUP BY name

Result:

{
  John: [Blue, Green]
}
{
  Mary: [NULL, Yellow, Pink, Pink]
}

Demo

1 Comment

Apparently OP is using SQL Server. Will this still work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.