假设我有一个只有一列的超简单表(称为useful_table
),如下所示:
+----------+
| a_number |
+----------+
| 2 |
| 4 |
| 8 |
+----------+
假设我有一个带有UNION
的查询:
SELECT
a_number
FROM
useful_table
WHERE
a_number = 2
UNION
SELECT
a_number + 1
FROM
useful_table
WHERE
a_number = 2
;
我希望结果是:
+----------+
| a_number |
+----------+
| 2 |
| 3 |
+----------+
示例查询在Oracle中运行,但应适用于其他方言。
此处的设置代码:
create table useful_table(a_number NUMBER);
insert into useful_table values (2);
insert into useful_table values (4);
insert into useful_table values (8);
是否可以转换此查询?
是否总是有可能将UNION
转换为替代项?
假设:
UNION
或UNION ALL
。UNION
的两侧都访问同一表中的数据,但是可能以不同的方式更改原始数据。答案 0 :(得分:2)
始终可以将UNION
重写为FULL OUTER JOIN
。
所以
SELECT
<expression1>
FROM
useful_table
WHERE
<predicate1>
UNION
SELECT
<expression2>
FROM
useful_table
WHERE
<predicate2>
;
将成为
SELECT DISTINCT COALESCE(u1.<expression1> , u2.<expression2> )
FROM useful_table u1
FULL OUTER JOIN useful_table u2
ON 1 = 0
WHERE u1.<predicate1>
OR u2.<predicate2>
或者在您的特定示例中
SELECT DISTINCT COALESCE(u1.a_number, u2.a_number + 1)
FROM useful_table u1
FULL OUTER JOIN useful_table u2
ON 1 = 0
WHERE u1.a_number = 2
OR u2.a_number = 2
答案 1 :(得分:1)
一种解决方案是使用CROSS JOIN
cte的CONNECT BY
复制输出行。
但是,一般来说,这是在以下假设下进行的:
WHERE
子句CONNECT BY
cte返回的递增整数来实现(仍然有相当大的操作余地)以下查询确实符合您的确切用例:
with data as (select level -1 l from dual connect by level <= 2)
select a_number + l
from useful_table, data
where a_number = 2
答案 2 :(得分:-3)
我将在没有其他方法的情况下使用Union。我一直发现,来自一个查询的联接和案例构造总是比联合表现更好。
但是,正如有人评论的那样,有时候行可以匹配两个案例标准,而案例逻辑无法实现。
查询是针对目标的,但我认为可以说不能总是取代Union。
在您的特定用例中,可以。