Reputation: 619
Using a UNION
clause in two SELECT
statements how can I guarantee the order of execution?
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.
I could use poclcdcl
column (or a virtual column) and then order by that, but in this case I need to get DISTINCT
rows.
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
Upvotes: 1
Views: 1639
Reputation: 94884
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. The ORDER BY
clause is simple in your case; in more complicated cases you'd use CASE WHEN
expressions in ORDER BY
.
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
. This is true, as for one combination of poclcdde, poclnpol, poclcdcl
you may have records with both pocltpsg
= '01' and '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).
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);
Upvotes: 3
Reputation: 36473
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:
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
Upvotes: 1
Reputation: 132570
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
Upvotes: 3