0

I am using 16 tables in query and try to optimized query with applying the below new changes. So we cannot use the group by, or union clause as it not be possible to apply in existing query due to performance issue.

I am looking for partition by rank/count/rownumber means the row level solution if possible.

select * FROM (
SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'AC' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'HA' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,1 AS SR FROM DUAL )
ORDER BY SR

With the example data above query I want:

  1. Keep all rows where SR=0
  2. Remove SR=1 row where CODE value exists in (SR=0)

For example the "AC" row with SR=1 is included because there is not an "AC" row with SR=0; and the "HA" row with SR=1 is removed because there is an "HA" row with SR=0.

Required output for this data:

HA   0
OF   0
HA   0
OF   0
XY   1
XY   1
AC   1

2 Answers 2

1

You could add a subquery and an analytic min():

select code, sr
from (
  select code, sr, min(sr) over (partition by code) as min_sr
  from (
    <your query>
  )
)
where sr = 0
or (sr = 1 and min_sr = 1)
order by sr;

For each row the subquery gets an additional column with the lowest SR for that code across all rows. The outer query then filters those so that rows with SR=1 are only kept if the minumum for that code is also 1; i.e. that there is no row for that code with SR=0.

With your dummy data that gives:

CODE         SR
---- ----------
OF            0 
OF            0 
HA            0 
HA            0 
XY            1 
XY            1 
AC            1 

SQL Fiddle demo using a CTE with your data, and showing the extra analytic-min column in the subquery as well.

You could also simplify that to just where sr = min_sr, but separating it into two clauses might make the logic and rules clearer.

Sign up to request clarification or add additional context in comments.

Comments

0

One might also try the following, putting the subquery above into a WITH:

WITH s AS (
    SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'AC' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'HA' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,1 AS SR FROM DUAL )
SELECT code, sr FROM s s1 -- 's1' is the table alias
 WHERE s1.sr = 0
    OR ( s1.sr = 1
     AND NOT EXISTS ( SELECT 1 FROM s s2 -- 's2' is the table alias
                       WHERE s2.code = s1.code
                         AND s2.sr = 0 ) )

Result:

HA  0
HA  0
OF  0
OF  0
AC  1
XY  1
XY  1

I'm divided on whether I think this is more readable than @Alex Poole's answer, though. But it does avoid the analytic function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.