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 alltype "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);