Примечания
- Я должен настаивать на том, чтобы вы НИКОГДА не использовали смешанные выражения соединения. Это означает, что если вы собираетесь использовать ключевые слова
JOIN
и LEFT JOIN
, не используйте ,
и наоборот. - Вы не дали понять, что вы ожидал, что ваш вывод будет выглядеть, поэтому я собираюсь использовать список, разделенный запятыми, но также покажу, как вы можете использовать массив.
- Я вставил это как комментарий, но стоит повторить: ANY_VALUE () агрегатная функция, но не работает в контексте PIVOT https://community.snowflake.com/s/question/0D50Z00008uVHTYSA4/anyvalue-does-not-work-on-pivot
Параметры запроса
Опция 1 - Встроенный свод (не рекомендуется, так как его сложнее читать, и подзапрос сводки нельзя использовать повторно)
select
p.ProductId
, p.name
, p.description
, p.brand
, p.model
, listagg(temp.body,', ') as body
, listagg(temp.DoorNum,', ') as doornum1
, arrayagg(temp.DoorNum) as doornum2
from
Product p
left join
ProductionCharacteristic pc
on p.ProductId = pc.ProductId
join (
select CharacteristicId, body, doornum
from Characteristic c
pivot (max(c.name) for c.type IN ('Body' , 'DoorNum')) as p (CharacteristicId, value, body, doornum)
) temp
on pc.CharacteristicId = temp.CharacteristicId
group by 1,2,3,4,5
;
Вариант 2 - сводка в CTE (рекомендуется)
with temp as (
select CharacteristicId, body, doornum
from Characteristic c
pivot (max(c.name) for c.type IN ('Body' , 'DoorNum')) as p (CharacteristicId, value, body, doornum)
)
select
p.ProductId
, p.name
, p.description
, p.brand
, p.model
, listagg(temp.body,', ') as body
, listagg(temp.DoorNum,', ') as doornum1
, arrayagg(temp.DoorNum) as doornum2
from
Product p
left join
ProductionCharacteristic pc
on p.ProductId = pc.ProductId
join temp
on pc.CharacteristicId = temp.CharacteristicId
group by 1,2,3,4,5
;
Вариант 3 - боковое соединение (Как коррелированный подзапрос)
select
p.ProductId
, p.name
, p.description
, p.brand
, p.model
, temp.body
, temp.doornum1
, temp.doornum2
from
Product p
join lateral (
select listagg(iff(type = 'Body',name,null),', ') as body
,listagg(iff(type = 'DoorNum',name,null),', ') as doornum1
,arrayagg(iff(type = 'DoorNum',name,null)) as doornum2
from Characteristic c
join ProductionCharacteristic pc
on pc.CharacteristicId = c.CharacteristicId
where p.ProductId = pc.ProductId
) temp
;
Надеюсь, это поможет.