问题
I have a table of products with their owners. Each owner is in their own row and has an owner type of either primary or secondary. Not every product has a secondary owner.
I need to get a table grouped by product with the primary owner in one column and all the secondary owners concatenated in a second column. If a product has multiple primary owners it should select the first one and the rest go to the secondary owners. If a product doesn't have a primary owner then it should just select the first/any secondary owner.
This is an input table:
+---------+------------+----------+
| Product | Owner Type | Owner |
+---------+------------+----------+
| a | primary | one |
| a | secondary | two |
| a | secondary | three |
| b | primary | four |
| b | secondary | five |
| c | primary | six |
| d | secondary | seven |
| e | secondary | eight |
| e | secondary | nine |
| f | primary | ten |
| f | primary | eleven |
| f | secondary | twelve |
| f | secondary | thirteen |
+---------+------------+----------+
The expected result is:
+---------+---------------+--------------------------+
| Product | Primary Owner | Secondary Owners |
+---------+---------------+--------------------------+
| a | one | two, three |
| b | four | five |
| c | six | |
| d | seven | |
| e | eight | nine |
| f | ten | eleven, twelve, thirteen |
+---------+---------------+--------------------------+
If you notice, products d
and e
don't have a primary owner so it picks the first secondary owner and then doesn't include it again in the secondary owner column. Similar for product f
that has two primary owner.
I know how to group
by product and use FOR XML PATH
to concatenate rows/fields. In the group
I know how to select the first product where Owner Type
is primary
. What I cannot figure out is the logic that would be needed to pick the first primary owner and exclude it from the secondary owner column and/or select the first secondary owner if there is no primary owner and exclude it from the secondary owner column.
I don't even know where to start with the SQL.
Any ideas?
回答1:
One way to do this is assigning row numbers prioritizing owner_type='Primary' rows. Then get the first row as the primary owner and group_concat
others to be secondary owners.
select product
,max(case when rnum=1 then owner end) as primary_owner
,group_concat(case when rnum<>1 then owner end order by rnum) as secondary_owners
from (select product,owner_type,owner,
@rn:=case when @prev_product=product then @rn+1 else 1 end as rnum,
@prev_product:=product
from tablename
cross join (select @rn:=0,@prev_product:='',@prev) r
order by product,owner_type='Primary',owner
) t
group by product
order by 1
Sample Demo
来源:https://stackoverflow.com/questions/43746314/sql-to-group-table-of-product-owners-with-a-column-for-primary-owner-and-concate