【问题标题】:Oracle SQL combine two columns into one without UNIONOracle SQL 不使用 UNION 将两列合二为一
【发布时间】:2017-02-21 08:59:25
【问题描述】:

在 ORACLE 11G 中,我有一个带有这种输出的 SELECT:

COL_A       COL_B
-------     -------
BCS         (null)
(null)      FFG
VKD         FIU
...

我想得到这个:

MY_ALIAS
---------
BCD
FFG
VKD
FIU
...

COL_A 和 COL_B 来自同一个表。查询有点复杂。

如您所见,行有 3 种类型:COL_A 有值,COL_B 为空,相反,最后两列都有值。

我知道这可以通过 UNION 以这种方式完成:

SELECT MY_ALIAS FROM (

    SELECT (COL_A) AS MY_ALIAS
    WHERE <lots of conditions here>
        AND COL_A IS NOT NULL
    UNION
    SELECT (COL_B) AS MY_ALIAS
    WHERE <lots of conditions here>
        AND COL_B IS NOT NULL
)

这样,WHERE 子句中的条件将完全相同,我想避免它。

有没有什么方法可以在不重复和没有 PL/SQL 的情况下实现这一点,只需一个 SELECT 查询?

编辑删除了避免 UNION 子句的需要。我回答的主要目的是避免重复。

谢谢!

【问题讨论】:

  • WHERE &lt;lots of conditions here&gt; 移到派生表之外。 (更好的代码,更容易维护。)
  • 我试过你的解决方案,它有效,谢谢 jarlh!

标签: sql oracle


【解决方案1】:

您可以尝试使用UNPIVOT FUNCTION

SELECT 
   MY_ALIAS 
FROM 
(
    SELECT COL_A, COL_B AS MY_ALIAS
    WHERE <lots of conditions here>
) T UNPIVOT (MY_ALIAS FOR COL IN (COL_A, COL_B))

【讨论】:

  • Coalesce 在这里不起作用,因为两列都可能有一个值(非空)
  • 对不起,我误解了你的问题。我已经编辑了答案以在 ORACLE 11G 中使用 UNPIVOT 函数。
  • 为了性能,你可以参考这个链接sqlsnippets.com/en/topic-12040.html。看来 UNPIVOT 功能会获得更好的性能。
  • 一个非常好的解决方案。 (不过,从子查询中删除 AS MY_ALIAS 并将 DISTINCT 添加到主查询中。无论如何,您不必将其设为主查询和子查询:SELECT DISTINCT my_alias FROM mytable WHERE &lt;lots of conditions here&gt; UNPIVOT (my_alias FOR col IN (col_a, col_b)))。
  • @spekdrum:别担心;我也认为这是最好的方法,而且我当然没有这个绝妙的主意来在这里使用UNPIVOT
【解决方案2】:

只需在包含所需列以及 where 子句中需要的所有列的所有记录上首先使用 UNION ALL。然后获取不同的值。

select distinct mycol
from
(
  select col_a as mycol, col_a, col_b, col_c from mytable
  union all
  select col_b as mycol, col_a, col_b, col_c from mytable
) data
where <lots of conditions here>;

【讨论】:

  • 它有效,但这里的关键不是 UNION ALL,而是在您的示例中将 移动到外部选择的事实。无论如何,我将此设置为正确答案。谢谢!
  • 嗯,UNION ALL 的那种 这里的关键。您必须用 where 子句中需要的所有列加上 col_a resp 组成行。 col_b,所以只有 UNION ALL 才有意义。只有这样,您才能应用 where 子句并删除重复项(使用 DISTINCT)。因此,而不是UNION ALL + DISTINCT 一步(即UNION),您将这两个进程分开。但是,无论如何,我的其他答案更好:-)
【解决方案3】:

使用WITH 子句应用您的标准:

with filtered as
(
  select col_a, col_b from mytable where <lots of conditions here>
)
select col_a from filtered
union
select col_b from filtered;

【讨论】:

  • 我试过这个并且它有效,但它比将大 where 子句放在 UNION 之外作为 jarlh 更冗长,你之前回答过。
  • 不过,这可能是最好的方法,因为您只合并您真正感兴趣的记录。(想象一个包含一百万条记录且只有十行符合您的条件的表。您想要将 100 万行粘合到另外 100 万行,然后才应用您的标准或简单地联合 10 加 10 行?)
  • 你是对的!我改变了正确的答案。谢谢!
猜你喜欢
  • 2016-11-28
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
相关资源
最近更新 更多