oracle group使用rank

时间:2014-06-02 20:04:30

标签: sql oracle oracle11g

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      

我想按类型对数据进行分组并调查Nr和我的查询的输出

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

因此,当我的子组类型/调查nr具有级别"所有级别"我将只显示该记录,如A -1和A2,否则我想显示所有记录,如案例B-1。

2 个答案:

答案 0 :(得分:0)

我只是将您拥有字符串'All Levels'的所有数据加入到该组中不存在的数据中。我有效地假设您的表在LEVEL,TYPE和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
                           )

请注意,LEVEL通常是列的无效名称;值得改变它。

答案 1 :(得分:0)

您可以使用RANK()函数和CASE语句执行此操作:

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"

演示:SQL Fiddle

RANK()会为PARTITION BY子句中指定的每个集合分配一个排名值,CASE中的ORDER BY语句用于将Lev的所有值设置为两个类别中的一个,优先考虑“所有级别”值。在没有WHERE子句的情况下运行此命令将帮助您了解RANK()函数的工作方式。