雪花的新手-具有连接和枢轴值的SQL语句问题

时间:2020-02-07 05:00:17

标签: sql join pivot snowflake-cloud-data-platform

我正在尝试通过将产品表链接到具有3对多表的特征表来对产品进行建模

例如

  • 产品(productId,品牌,描述,型号)
  • ProductCharacteristic(产品编号,特征编号)
  • 特征(characteristicId,类型,名称,值)

从这种结构中,我尝试将其返回到一个结果,以将具有特征和类型特征的值显示在选择语句中。

例如:

select distinct 
    p.ProductId, p.name, p.description, p.brand, p.model, body, DoorNum
from    
    Product p
left join   
    ProductionCharacteristic pc on p.ProductId = pc.ProductId,
    (select CharacteristicId, "'Body'" as body, "'DoorNum'" as DoorNum  
     from Characteristic c
     pivot (max(c.name) for c.type IN ('Body' , 'DoorNum')))  temp
where  
    pc.CharacteristicId = temp.CharacteristicId

问题1:any_Value是汇总函数吗?它枢轴不喜欢它,我改用max() 问题2:以上选择返回3行。有没有办法将其压缩到一个记录?

1 个答案:

答案 0 :(得分:0)

注释

  1. 我必须坚持要求您 从不 使用混合连接表达式。意味着如果您要使用关键字JOINLEFT JOIN,则不要使用 ,,反之亦然。
  2. 您没有明确说明您希望输出的结果如何,因此我将使用逗号分隔的列表,但还将显示如何使用数组。
  3. 我将其作为注释,但值得重复: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
;

希望这会有所帮助。

相关问题