ORACLE SQL 如何实现 UNION 子句但保持每个子句的顺序 SELECT
ORACLE SQL How to implement a UNION clause but maintain the order of each SELECT
在两个 SELECT
语句中使用 UNION
子句如何保证执行顺序?
例如:
SELECT a.poclcdde, a.poclnpol, a.poclcdcl
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION
SELECT a.poclcdde, a.poclnpol, a.poclcdcl
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02'
POCLCDDE POCLNPOL POCLCDCL
---------- ---------- ----------
100 1000001 202153
100 5001021 216450
100 9000386 8078
100 9900633 250056
100 9900634 250056
100 9901720 562223
100 9901763 562223
200 1000001 202153
200 5001021 216450
在这种情况下,如何保证第一条记录来自query1,其余记录来自query2。
我可以使用 poclcdcl
列(或虚拟列),然后按此排序,但在这种情况下,我需要获得 DISTINCT
行。
SELECT *
FROM (SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
1 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
2 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02')
ORDER BY TYPE
POCLCDDE POCLNPOL POCLCDCL TYPE
---------- ---------- ---------- ----------
200 1000001 202153 1
100 1000001 202153 1
100 9000386 8078 1
100 9900634 250056 2
100 9901720 562223 2
100 9901763 562223 2
200 5001021 216450 2
100 9000386 8078 2
100 5001021 216450 2
100 9900633 250056 2
我需要它按顺序交互每一行:第一个查询占上风。
谢谢
你可以这样做:
SELECT *
FROM (SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
1 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
2 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02'
AND NOT EXISTS (SELECT NULL
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01')
)
ORDER BY TYPE
您可以将 union all
与 type
"virtual" 列一起使用以获得正确的顺序,并对 row_number
分析函数的返回值使用过滤器在优先处理第一个查询的行时删除重复项:
with cte as (
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
1 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION ALL
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
2 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02'
)
select poclcdde, poclnpol, poclcdcl
from (select t.*,
row_number() over (
partition by t.poclcdde, t.poclnpol, t.poclcdcl
order by t.type) as rn
from cte t)
where rn = 1
order by type
您正在从同一个 table 中选择相同的列,因此您不需要两个查询,而只需要一个带有适当 WHERE
子句的查询。 ORDER BY
子句在您的情况下很简单;在更复杂的情况下,您将在 ORDER BY
.
中使用 CASE WHEN
表达式
select poclcdde, poclnpol, poclcdcl
from dtpocl
where poclcdcl in (216450, 562223, 250056, 202153, 8078)
and
(
(pocltpsg = '01' and poclcdce = 0)
or
pocltpsg = '02'
)
order by pocltpsg;
更新: 你说你得到重复项,但是一旦你使用 DISTINCT
,你就不能按 pocltpsg
排序。这是事实,对于 poclcdde, poclnpol, poclcdcl
的一种组合,您可能拥有同时具有 pocltpsg
= '01' 和 '02' 的记录。因此,您必须按 poclcdde, poclnpol, poclcdcl
进行聚合,然后决定是按 min(pocltpsg)
还是 max(pocltpsg)
(或任何其他与此相关的聚合)进行排序。
select poclcdde, poclnpol, poclcdcl
from dtpocl
where poclcdcl in (216450, 562223, 250056, 202153, 8078)
and
(
(pocltpsg = '01' and poclcdce = 0)
or
pocltpsg = '02'
)
group by poclcdde, poclnpol, poclcdcl
order by min(pocltpsg);
在两个 SELECT
语句中使用 UNION
子句如何保证执行顺序?
例如:
SELECT a.poclcdde, a.poclnpol, a.poclcdcl
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION
SELECT a.poclcdde, a.poclnpol, a.poclcdcl
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02'
POCLCDDE POCLNPOL POCLCDCL
---------- ---------- ----------
100 1000001 202153
100 5001021 216450
100 9000386 8078
100 9900633 250056
100 9900634 250056
100 9901720 562223
100 9901763 562223
200 1000001 202153
200 5001021 216450
在这种情况下,如何保证第一条记录来自query1,其余记录来自query2。
我可以使用 poclcdcl
列(或虚拟列),然后按此排序,但在这种情况下,我需要获得 DISTINCT
行。
SELECT *
FROM (SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
1 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
2 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02')
ORDER BY TYPE
POCLCDDE POCLNPOL POCLCDCL TYPE
---------- ---------- ---------- ----------
200 1000001 202153 1
100 1000001 202153 1
100 9000386 8078 1
100 9900634 250056 2
100 9901720 562223 2
100 9901763 562223 2
200 5001021 216450 2
100 9000386 8078 2
100 5001021 216450 2
100 9900633 250056 2
我需要它按顺序交互每一行:第一个查询占上风。 谢谢
你可以这样做:
SELECT *
FROM (SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
1 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
2 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02'
AND NOT EXISTS (SELECT NULL
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01')
)
ORDER BY TYPE
您可以将 union all
与 type
"virtual" 列一起使用以获得正确的顺序,并对 row_number
分析函数的返回值使用过滤器在优先处理第一个查询的行时删除重复项:
with cte as (
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
1 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLCDCE = 0
AND POCLTPSG = '01'
UNION ALL
SELECT a.poclcdde,
a.poclnpol,
a.poclcdcl,
2 AS TYPE
FROM dtpocl a
WHERE a.poclcdcl IN (216450,
562223,
250056,
202153,
8078)
AND POCLTPSG = '02'
)
select poclcdde, poclnpol, poclcdcl
from (select t.*,
row_number() over (
partition by t.poclcdde, t.poclnpol, t.poclcdcl
order by t.type) as rn
from cte t)
where rn = 1
order by type
您正在从同一个 table 中选择相同的列,因此您不需要两个查询,而只需要一个带有适当 WHERE
子句的查询。 ORDER BY
子句在您的情况下很简单;在更复杂的情况下,您将在 ORDER BY
.
CASE WHEN
表达式
select poclcdde, poclnpol, poclcdcl
from dtpocl
where poclcdcl in (216450, 562223, 250056, 202153, 8078)
and
(
(pocltpsg = '01' and poclcdce = 0)
or
pocltpsg = '02'
)
order by pocltpsg;
更新: 你说你得到重复项,但是一旦你使用 DISTINCT
,你就不能按 pocltpsg
排序。这是事实,对于 poclcdde, poclnpol, poclcdcl
的一种组合,您可能拥有同时具有 pocltpsg
= '01' 和 '02' 的记录。因此,您必须按 poclcdde, poclnpol, poclcdcl
进行聚合,然后决定是按 min(pocltpsg)
还是 max(pocltpsg)
(或任何其他与此相关的聚合)进行排序。
select poclcdde, poclnpol, poclcdcl
from dtpocl
where poclcdcl in (216450, 562223, 250056, 202153, 8078)
and
(
(pocltpsg = '01' and poclcdce = 0)
or
pocltpsg = '02'
)
group by poclcdde, poclnpol, poclcdcl
order by min(pocltpsg);