我有一个表可能是由listagg引起的,类似于:
# select * from s;
s
-----------
a,c,b,d,a
b,e,c,d,f
(2 rows)
如何将其更改为这组行:
a
c
b
d
a
b
e
c
d
f
答案 0 :(得分:2)
在redshift中,您可以加入数字表,并将其用作拆分索引:
--with recursive Numbers as (
-- select 1 as i
-- union all
-- select i + 1 as i from Numbers where i <= 5
--)
with Numbers(i) as (
select 1 union
select 2 union
select 3 union
select 4 union
select 5
)
select split_part(s,',', i) from Numbers, s ORDER by s,i;
编辑:redshift似乎不支持递归子查询,只支持postgres。 :(
答案 1 :(得分:0)
Oracle 11g R2架构设置:
create table s(
col varchar2(20) );
insert into s values('a,c,b,d,a');
insert into s values('b,e,c,d,f');
查询1 :
SELECT REGEXP_SUBSTR(t1.col, '([^,])+', 1, t2.COLUMN_VALUE )
FROM s t1 CROSS JOIN
TABLE
(
CAST
(
MULTISET
(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT(t1.col, '([^,])+')
)
AS SYS.odciNumberList
)
) t2
<强> Results 强>:
| REGEXP_SUBSTR(T1.COL,'([^,])+',1,T2.COLUMN_VALUE) |
|---------------------------------------------------|
| a |
| c |
| b |
| d |
| a |
| b |
| e |
| c |
| d |
| f |
答案 2 :(得分:0)
由于已将其标记为Redshift,并且到目前为止,尚无答案,这是无法正确撤消Redshift中的LISTAGG的完整概述,这是解决所有用例的代码:
CREATE TEMPORARY TABLE s (
s varchar(255)
);
INSERT INTO s VALUES('a,c,b,d,a');
INSERT INTO s VALUES('b,e,c,d,f');
SELECT
TRIM(split_part(s.s,',',R::smallint)) AS s
FROM s
LEFT JOIN (
SELECT
ROW_NUMBER() OVER (PARTITION BY 1) AS R
FROM any_large_table
LIMIT 1000
) extend_number
ON (SELECT MAX(regexp_count(s.s,',')+1) FROM s) >= extend_number.R
AND NULLIF(TRIM(split_part(s.s,',',extend_number.R::smallint)),'') IS NOT NULL;
DROP TABLE s;
其中“ any_large_table”是您已经在redshift中拥有的任何表,该表具有足够的记录供您使用,这取决于每个记录的列表将包含的元素数量(即,在上述情况下,我确保它最多为-千条记录)。不幸的是,据我所知,generate_series函数在Redshift中无法正常工作,这是唯一的方法。
另一建议是检查是否可以在可能的值已经列出list_agg之前获得它们。从上面的代码中可以看到,它看起来相当复杂,并且如果您使事情保持简单(也就是说,只要有机会,就可以节省很多维护时间)。