在红移中撤消LISTAGG

时间:2015-09-25 16:38:25

标签: sql amazon-redshift

我有一个表可能是由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

3 个答案:

答案 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)

SQL Fiddle

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之前获得它们。从上面的代码中可以看到,它看起来相当复杂,并且如果您使事情保持简单(也就是说,只要有机会,就可以节省很多维护时间)。

相关问题