2009-06-09 41 views
3

这是我拥有的数据样本。高级分组,不使用子查询

-ID-  -Rank-  -Type-  -Status- -Amount- 
1142474  2  Under Offer Approved 23 
1148492  1  Present  Current  56 
1148492  2  Under Offer Approved 3 
2273605  1  Present  Current  24 

在ID相同的情况下,我只想要排名最高的记录。所以查询的最终结果。

-ID-  -Rank-  -Type-  -Status- -Amount- 
1142474  2  Under Offer Approved 23 
1148492  1  Present  Current  56 
2273605  1  Present  Current  24 

我们得到原始数据集是一个昂贵的操作,所以由ID做,然后分钟军衔然后加入回再次到数据集上。因此查询需要以另一种方式完成其工作。

干杯 安东尼

一般可用

回答

1
select t1.id 
     , t1.rank 
     , t1.type 
     , t1.status 
     , t1.amount 

from my_table t1 

     left outer join my_table as t2 
     on t1.id = t2.id 
    and 
     t2.rank < t1.rank 

where t2.id is null 
+0

在这种情况下t2是什么? – 2009-06-09 06:15:41

+0

@Anthony:t2的连接也被称为自连接。这是同一张表的另一个副本。它工作的原因是我们在谓词(连接条件和WHERE子句)中指定我们想要排除每个id的最高排序项目以外的所有项目。 – bernie 2009-06-09 06:28:06

+0

@adam:问题是,从my_table中获取数据非常昂贵(即在2到6秒之间),因此我想避免再次加入到表格中... – 2009-06-09 06:52:02

0

选项包括:

  • 存放在临时表中所示的数据,然后查询临时表。
  • 使用WITH子句来定义复杂查询,然后让DBMS整理查询。

WITH子句有效地允许您给一个子查询命名;如果可能的话,优化器将避免重新评估它。 TEMP表格解决方案可能是最简单的。这将做ID和MIN(等级)的GROUP BY,并加入回来。

2
SELECT * FROM TheTable 
WHERE 1 = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Rank DESC) 
6

这将工作:

with temp as (
select *, row_number() over (partition by id order by rank) as rownum 
from table_name 
) 
select * from temp where rownum = 1 

会给每个ID只能有一个记录,其中级为最低数量

0

为什么找数据集那么贵,我看没什么可怕的这里复杂。你有你需要的索引,是使用它们的查询吗?统计数据是否过时?