简体   繁体   中英

oracle group by using rank

TableOne

Id1| Level     |Type|Survey Nr
--------------------------------
  1| Level 1   |A   |1  
  2| Level 2   |A   |1
  3| Level 3   |A   |1
  4| All Levels|A   |1   
 ------------------------------- 
  5| Level 1   |B   |1 
  6| Level 2   |B   |1
  7| Level 4   |B   |1
 -------------------------------- 
  8| Level 1   |A   |2 
  9| Level 2   |A   |2
 10| Level 3   |A   |2
 11| All Levels|A   |2      

I want to group my data by type and survey Nr an the output of my query to be

1. All levels   |A   |1
2. Level 1      |B   |1 
3. Level 2      |B   |1
4. Level 4      |B   |1
5. All Levels   |A   |2

So when my subgroup Type/survey nr have level "All Levels" i will only display that record like in case A -1 and A2 else i want to display all records like in case B-1.

I'd just UNION ALL the data where you have the string 'All Levels' to the data where it doesn't exist within that group. I've effectively assumed that your table is unique on LEVEL, TYPE and SURVEY_NR.

with base_data as (
 select a
   from the_table
        )
select level, type, survey_nr
  from base_data
 where level = 'All Levels'
 union all
select level, type, survey_nr
  from base_data
 where not exists ( select 1
                      from base_data
                     where level = 'All Levels'
                       and type = x.type
                       and survey_nr = x.survey_nr
                           )

Please note that LEVEL is normally an invalid name for a column; it's worth changing it.

You can do this with the RANK() function and a CASE statement:

WITH cte AS (SELECT "Id1","Lev","Type","Survey_Nr"
                    ,RANK() OVER (PARTITION BY "Type","Survey_Nr" ORDER BY CASE WHEN "Lev" = 'All Levels' THEN 0 ELSE 1 END) AS RN
             FROM Table1)
SELECT *
FROM cte
WHERE RN = 1
ORDER BY "Id1"

Demo: SQL Fiddle

RANK() will assign a rank value to each set indicated in the PARTITION BY clause, and the CASE statement in the ORDER BY is used to set all values of Lev into one of two categories, giving preference to the "All Levels" values. Running this without the WHERE clause will help you see how the RANK() function is working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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