将同一子查询的列合并为单个列的SQL Union

4

我希望选出一个仅包含同一表中列1、2、3、4内容的并集的单独列。由于SUBQUERYCONDITION很复杂,我感觉这样做是错误的方式:

SELECT COL1 FROM SUBQUERY WHERE CONDITION 
UNION
SELECT COL2 FROM SUBQUERY WHERE CONDITION 
UNION
SELECT COL3 FROM SUBQUERY WHERE CONDITION 
UNION
SELECT COL4 FROM SUBQUERY WHERE CONDITION 
UNION
SELECT COL5 FROM SUBQUERY WHERE CONDITION 

由于这个查询在性能和编码风格上都不太好,因此在Oracle中是否有更好的语法呢?

P.S.

如果以下伪代码是正确的,那就完美了:

SELECT COL1 UNION COL2 UNION COL3 UNION COL4 
FROM 
    SUBQUERY WHERE CONDITION;

你的语法(顶部)看起来很好,我更倾向于质疑你的数据库设计,这导致了某些原因在不同列中具有明显相似的信息。 - Tim Biegeleisen
这些 SUBQUERY 是相同的吗?只是 WHERE CONDITION 不同吗? - D-Shih
也许使用 with 子句可以帮助一点。with SUBQUERY as (select ...) SELECT DISTINCT * FROM ... - PKey
@D-Shih,条件也是一样的。我将尝试Plirkee建议的查询(他可以将评论作为答案)。 - jimifiki
1
UNION 上使用 DISTINCT 是多余的。UNION 操作会删除重复项。你是不是想用 UNION ALL - Kaushik Nayak
1
虽然使用联合(或联合所有)的方法可以实现,但这意味着您需要多次查询同一张表。我更喜欢Dmitry提供的"unpivot"解决方案,它只需要一次对表的操作,因此应该具有更高的性能。 - Boneist
3个回答

4
你可以使用 UNPIVOT:
select * from 
    (select 'a' col1, 'b' col2, 'c' col3, 'd' col4, 'e' col5 from dual)
unpivot (
  united_columns for subquery_column in ("COL1", "COL2", "COL3", "COL4", "COL5"));

SUBQUERY_COLUMN UNITED_COLUMNS
--------------- --------------
COL1            a              
COL2            b              
COL3            c              
COL4            d              
COL5            e          

请使用 select * from subquery where condition 替代。
select 'a' col1, 'b' col2, 'c' col3, 'd' col4, 'e' col5 from dual

点击链接了解更多有关UNPIVOT的信息,以便更好地理解:


3

如果所有列的条件和子查询都相同,则可以使用以下语法:

with SUBQUERY as ( select * from mytable WHERE CONDITION)  
SELECT DISTINCT * FROM 
(
SELECT COL1 FROM SUBQUERY 
UNION
SELECT COL2 FROM SUBQUERY 
UNION
SELECT COL3 FROM SUBQUERY 
UNION
SELECT COL4 FROM SUBQUERY 
UNION
SELECT COL5 FROM SUBQUERY 
)

更多信息请查看这里:with子句


在我的情况下,这比单独的工会查询要贵。 - Sarfaraz78615

1

如果您使用的是旧版本的Oracle,您可以使用 cross join

select distinct (case when n.n = 1 then col1
                      when n.n = 2 then col2
                      when n.n = 3 then col3
                      when n.n = 4 then col4
                      when n.n = 5 then col5
                 end) as col
from subquery cross join
     (select 1 as n from dual union all
      select 2 from dual union all
      select 3 from dual union all
      select 4 from dual union all
      select 5 from dual
     ) n
where . . .;

个人而言,我更喜欢使用横向连接(lateral join)而不是 pivot,因为横向连接更强大(尽管在这种情况下它们做的事情相同)。语法如下:

select distinct x.col
from subquery s cross apply
     (select s.col1 as col from dual union all
      select s.col2 from dual union all
      select s.col3 from dual union all
      select s.col4 from dual union all
      select s.col5 from dual
     ) x
where . . .;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接