问题描述
我想将逗号分隔的值转换为 Redshift 中的行
例如:
store |location |products
-----------------------------
1 |New York |fruit,drinks,candy...
所需的输出是:
store |location | products
-------------------------------
1 |New York | fruit
1 |New York | drinks
1 |New York | candy
是否有任何简单的解决方案可以根据分隔符拆分单词并转换为行?我正在研究这个解决方案,但它仍然不起作用:https://help.looker.com/hc/en-us/articles/360024266693-Splitting-Strings-into-Rows-in-the-Absence-of-Table-Generating-Functions
任何建议将不胜感激。
解决方法
如果你知道值的最大值,我想你可以split_part()
:
select t.store,t.location,split_part(products,',n.n) as product
from t join
(select 1 as n union all
select 2 union all
select 3 union all
select 4
) n
on split_part(products,n.n) <> '';
您也可以使用:
select t.store,1) as product
from t
union all
select t.store,2) as product
from t
where split_part(products,2) <> ''
union all
select t.store,3) as product
from t
where split_part(products,3) <> ''
union all
select t.store,4) as product
from t
where split_part(products,4) <> ''
union all
. . .
,
首先,您需要创建一个数字表,因为加入另一个表是 redshift 将一行变成多行的唯一方法(没有展平或取消嵌套功能)。
- 例如,一个包含 1024 行且其中值为 1..1024 的表
然后你可以加入并使用split_part()
SELECT
yourTable.*,numbers.ordinal,split_part(your_table.products,numbers.ordinal) AS product
FROM
yourTable
INNER JOIN
numbers
ON numbers.ordinal >= 1
AND numbers.ordinal <= regexp_count(your_table.products,') + 1
但是……
Redshift 在预测所需行数方面很糟糕。它将连接整个 1024 行,然后拒绝不匹配的行。
它的表现就像一只狗。
因为设计假设是这样的处理总是在加载到 Redshift 之前完成。
,MYSQL 也不错
CREATE TABLE test
SELECT 1 store,'New York' location,'fruit,drinks,candy' products;
SELECT store,location,product
FROM test
CROSS JOIN JSON_TABLE(CONCAT('["',REPLACE(products,'","'),'"]'),"$[*]" COLUMNS (product VARCHAR(255) PATH "$")) jsontable
store | 位置 | 产品 |
---|---|---|
1 | 纽约 | 水果 |
1 | 纽约 | 饮料 |
1 | 纽约 | 糖果 |
dbfiddle here
,在 MySQL 中,这最多适用于四个逗号分隔的值。注意 UNION
,而不是 UNION ALL
。 Fiddle
SELECT store,TRIM(SUBSTRING_INDEX(products,1)) product
FROM inventory
UNION
SELECT store,TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(products,2),-1))
FROM inventory
UNION
SELECT store,3),4),-1))
FROM inventory
我会回应其他人所说的话。顺便说一句,逗号分隔值是一种糟糕的表格设计。
- 它使 SQL 变得丑陋。能够阅读和推理 SQL 非常重要。清晰总是胜利。
- 而且,AWS 股东会因此而喜欢您,因为您将在 redshift 上花费很多额外的钱。
CREATE TABLE temptbl
(
store INT,location NVARCHAR(MAX),products NVARCHAR(MAX)
)
INSERT temptbl SELECT 1,'New York','Fruit,candy'
创建的表的输出
select * from temptbl
;WITH tmp(store,DataItem,products) AS
(
SELECT
store,LEFT(products,CHARINDEX(',products + ',') - 1),STUFF(products,1,'),'')
FROM temptbl
UNION all
SELECT
store,'')
FROM tmp
WHERE
products > ''
)
SELECT
store,DataItem
FROM tmp
您希望多行中的逗号分隔值: 运行以上命令后您想要的输出:
希望你找到你的解决方案:)))