将列中逗号分隔的值转换为行

问题描述

我想将逗号分隔的值转换为 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 ALLFiddle

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'

创建的表的输出

output

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

您希望多行中的逗号分隔值: 运行以上命令后您想要的输出:

output

希望你找到你的解决方案:)))