具有不同值的同一列到单个输出
Same column with different values into single output
问候 :)
这可能是一个简单的雪花问题,但我正在努力解决这个问题..
我想将同一列中的不同值收集到一个输出中。为了给你更多的背景信息,我在一个客户 table 工作,那个客户注册了 2 个手机号码,所以在输出中两次给我同一个客户,但每个记录都有不同的 phone 号码(以及我们数据库中同一列中的那些数字)所以,我只想获取一条记录并将这两个数字收集在同一列中。
我正在做分析,所以只是从数据库中读取我在这里没有改变任何东西。
提前谢谢你:)
---- 更多说明:
我不能使用 listagg() 因为数字存储在同一列中,我的目标是将它们收集在单个输出中:)
所以把它剥离下来,我有一个 table 和 customer_id
和 phone
像这样:
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"
问候 :)
这可能是一个简单的雪花问题,但我正在努力解决这个问题..
我想将同一列中的不同值收集到一个输出中。为了给你更多的背景信息,我在一个客户 table 工作,那个客户注册了 2 个手机号码,所以在输出中两次给我同一个客户,但每个记录都有不同的 phone 号码(以及我们数据库中同一列中的那些数字)所以,我只想获取一条记录并将这两个数字收集在同一列中。
我正在做分析,所以只是从数据库中读取我在这里没有改变任何东西。
提前谢谢你:)
---- 更多说明: 我不能使用 listagg() 因为数字存储在同一列中,我的目标是将它们收集在单个输出中:)
所以把它剥离下来,我有一个 table 和 customer_id
和 phone
像这样:
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" |