简体   繁体   English

ORACLE SQL如何实现UNION子句但保持每个SELECT的顺序

[英]ORACLE SQL How to implement a UNION clause but maintain the order of each SELECT

Using a UNION clause in two SELECT statements how can I guarantee the order of execution? 在两个SELECT语句中使用UNION子句,如何保证执行顺序? For example: 例如:

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

In this case, How can I guarantee that the first records are from query1 and the rest are from query2. 在这种情况下,如何保证第一条记录来自query1,其余记录来自query2。 I could use poclcdcl column (or a virtual column) and then order by that, but in this case I need to get DISTINCT rows. 我可以使用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

I need this to interact each row by that order: the first query prevails. 我需要它按该顺序交互每一行:以第一个查询为准。 Thanks 谢谢

You could do this: 您可以这样做:

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

You are selecting the same columns from the same table, so you don't need two queries, but just one with an appropriate WHERE clause. 您从同一张表中选择相同的列,因此您不需要两个查询,而只需要一个带有适当WHERE子句的查询。 The ORDER BY clause is simple in your case; 在您的情况下, ORDER BY子句很简单; in more complicated cases you'd use CASE WHEN expressions in 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;

UPDATE: You say that you get duplicates, but once you use DISTINCT , you are not allowed to sort by pocltpsg . 更新:您说得到重复项,但是一旦使用DISTINCT ,就不允许按pocltpsg进行排序。 This is true, as for one combination of poclcdde, poclnpol, poclcdcl you may have records with both pocltpsg = '01' and '02'. 的确如此,因为poclcdde, poclnpol, poclcdcl一种组合可能同时具有pocltpsg = pocltpsg '和'02'的记录。 So you would have to aggregate by poclcdde, poclnpol, poclcdcl and decide whether to sort by min(pocltpsg) or max(pocltpsg) (or any other aggregate for that matter). 因此,您将必须按poclcdde, poclnpol, poclcdcl进行汇总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);

You can use a union all with the type "virtual" column to get the right order, and use a filter on the returned value of the row_number analytic function to remove the duplicates while prioritizing the first query's rows: 您可以使用type “ virtual”列的union all来获得正确的顺序,并在对第一个查询的行进行优先级排序时,对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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM