postgres选择regexp_split_to_table生成的行的位置,其中union抛出错误

时间:2013-08-12 09:08:06

标签: postgresql

我有一个表'my_table',其中两列(c1,c2)以完全相同的格式保存数据'1,2,3,4; 5,6,7,8' 我使用regexp_split_to_table将它们分成行,我试图选择非空行。

SELECT * from 
 (SELECT '1' as param1 ,'2' as param2, param3 FROM
  ((select regexp_split_to_table(my_table.c1, ';') as param3
   FROM  my_table)
 UNION
  (select regexp_split_to_table(my_table.c2, ';') as param3
   FROM  my_table)) AS a) as b

 where param3 is not null

运行此查询会出现以下错误:

set-valued function called in context that cannot accept a set

如果我删除联合并仅从其中一个列中选择,或者通过其中一个字段(param1 / param2)进行筛选,则查询可以正常工作。 我认为这可能是数据的问题所以我尝试从同一列中选择两次:

SELECT * from 
 (SELECT '1' as param1 ,'2' as param2, param3 FROM
  ((select regexp_split_to_table(my_table.c1, ';') as param3
   FROM  my_table)
 UNION
  (select regexp_split_to_table(my_table.c1, ';') as param3
   FROM  my_table)) AS a) as b

 where param3 is not null

但我仍然得到同样的错误。 有谁知道如何解决这个问题? 谢谢!

1 个答案:

答案 0 :(得分:3)

我建议使用CTE而不是子查询并格式化您的查询。这是我认为你需要的查询:

with cte1 as (
  select regexp_split_to_table(t.c1, ';') as param3
  from my_table as t
  union all
  select regexp_split_to_table(t.c2, ';') as param3
  from my_table as t
)
select '1' as param1 ,'2' as param2, c.param3
from cte1 as c
where c.param3 is not null

sql fiddle demo

注意:我不知道您的查询中是否需要重复项,因此如果您不需要重复项,请使用union代替union all

<强>更新

with cte1 as (
  select regexp_split_to_table(t.c1, ';') as param3
  from my_table as t
  union all
  select regexp_split_to_table(t.c2, ';') as param3
  from my_table as t
), cte2 as (
  select regexp_split_to_table(c.param3, ',') as param3
  from cte1 as c
  where c.param3 is not null and c.param3 <> ''
)
select *
from cte2 as c
where c.param3 is not null and c.param3 <> ''

sql fiddle demo

update2 甚至可以使用一个正则表达式

with cte1 as (
    select c1 as param3 from my_table
    union all
    select c2 as param3 from my_table
), cte2 as (
  select regexp_split_to_table(param3, '(;|,)') as param3
  from cte1
)
select '1' as param1 ,'2' as param2, c.param3
from cte2 as c
where nullif(c.param3, '') <> ''

sql fiddle demo