具有不同值的同一列到单个输出

Same column with different values into single output

问候 :)

这可能是一个简单的雪花问题,但我正在努力解决这个问题..

我想将同一列中的不同值收集到一个输出中。为了给你更多的背景信息,我在一个客户 table 工作,那个客户注册了 2 个手机号码,所以在输出中两次给我同一个客户,但每个记录都有不同的 phone 号码(以及我们数据库中同一列中的那些数字)所以,我只想获取一条记录并将这两个数字收集在同一列中。

我正在做分析,所以只是从数据库中读取我在这里没有改变任何东西。

提前谢谢你:)

---- 更多说明: 我不能使用 listagg() 因为数字存储在同一列中,我的目标是将它们收集在单个输出中:)

所以把它剥离下来,我有一个 table 和 customer_idphone

像这样:

SELECT
    customer_id,
    phone
FROM VALUES 
   (123, '555-1234-999'),
   (123, '555-5555-999'),
   (678, '555-6162-999')
   v(customer_id, phone);

给你你的行数:

CUSTOMER_ID PHONE
123 555-1234-999
123 555-5555-999
678 555-6162-999

我们可以偷懒(对我来说)把它变成一个数组:

SELECT
    customer_id,
    ARRAY_AGG(phone) as phones
FROM VALUES 
   (123, '555-1234-999'),
   (123, '555-5555-999'),
   (678, '555-6162-999')
   v(customer_id, phone)
GROUP BY 1 
ORDER BY 1;

给出:

CUSTOMER_ID PHONES
123 [ "555-1234-999", "555-5555-999" ]
678 [ "555-6162-999" ]

更进一步可能是添加一个 WITHIN GROUP 子句来订购那些 phones:

SELECT
    customer_id,
    ARRAY_AGG(phone) WITHIN GROUP (ORDER BY phone) as phones
FROM VALUES 
   (123, '555-1234-999'),
   (123, '555-5555-999'),
   (678, '555-6162-999')
   v(customer_id, phone)
GROUP BY 1 
ORDER BY 1;

可以换栏目下单,我这里加了个假账号,运气好:

SELECT
    customer_id,
    ARRAY_AGG(phone) WITHIN GROUP (ORDER BY account) as phones
FROM VALUES 
   (123, '555-1234-999',2),
   (123, '555-5555-999',1),
   (678, '555-6162-999',1)
   v(customer_id, phone, account)
GROUP BY 1 
ORDER BY 1;

或者我们可以做一个自我 LEFT JOIN 知道“每个客户只有 2 phone”

WITH data AS (
  SELECT *
  FROM VALUES 
   (123, '555-1234-999',2),
   (123, '555-5555-999',1),
   (678, '555-6162-999',1)
   v(customer_id, phone, account)
)
SELECT
    a.customer_id,
    a.phone,
    b.phone
FROM data AS a
LEFT JOIN data AS b 
    ON a.customer_id = b.customer_id and a.account = 1 and b.account = 2
ORDER BY 1;

给出:

CUSTOMER_ID PHONE PHONE
123 555-1234-999
123 555-5555-999 555-1234-999
678 555-6162-999

没错,所以 multi-join 不是想要的,很好,因为它很丑。

不确定为什么不能使用 LIST_AGG,因为您可以将标记包装在一个模式中,然后将其定界。但真的 ARRAY_AGG 更好。

SELECT
    customer_id,
    LISTAGG('"'|| phone ||'"',',' ) as phones
FROM VALUES 
   (123, '555-1234-999'),
   (123, '555-5555-999'),
   (678, '555-6162-999')
   v(customer_id, phone)
GROUP BY 1 
ORDER BY 1;

给出:

CUSTOMER_ID PHONES
123 "555-1234-999","555-5555-999"
678 "555-6162-999"