2017-09-10 39 views
1

假设我有一个表XYZ包含如下数据: -SQL查询最小的一个

ID PNO SEQ 
10 2345 1 
12 1234 1 
13 4567 2 
15 1234 3 
16 5436 4 
21 1324 5 
26 5675 5 
27 3423 5 
29 6864 5 
31 2432 6 

现在我需要查询的输出为行包含重复的序列,但除SEQ.The输出的最小ID应该是: -

ID PNO SEQ 
12 1234 1 
26 5675 5 
27 3423 5 
29 6864 5 

我尝试使用下面query.It根据我的工作,但我需要在降低成本,优化it.Please帮助。

select ID,PNO,SEQ 
FROM XYZ 
WHERE SEQ IN 
(SELECT SEQ 
FROM XYZ 
GROUP BY SEQ having count(*) > 1) 
and ID NOT IN (SELECT MIN(ID) from XYZ GROUP BY SEQ) 
+0

您使用的是哪个版本的Oracle? (通过运行'select * from v $ version'来报告) – mathguy

回答

1

简化查询的一种方法是使用窗口函数。

SELECT id,pno,seq 
FROM (SELECT x.* 
     ,count(*) over(partition by seq) as cnt_per_seq 
     ,min(id) over(partition by seq) as min_id_per_seq 
     FROM XYZ x 
    ) x 
WHERE cnt_per_seq > 1 AND id <> min_id_per_seq 
0

使用窗口函数。一个就足够了。为了您的确切查询:

SELECT ID, PNO, SEQ 
FROM (SELECT XYZ.*, MIN(ID) OVER (PARTITION BY SEQ) as min_seq 
     FROM XYZ 
    ) t 
WHERE id > MIN(ID); 

对于给定的SEQ,一旦被选中,只有当存在针对SEQ多个值。

还值得一检查,如果这是更快:

select id, pno, seq 
from xyz 
where id > (select min(xyz2.id) from xyz xyz2 where xyz2.seq = xyz.seq); 

Oracle有一个相当不错的优化,因此性能可能非常相似。

0

你想显示其存在具有相同seq另一个记录和一个较小的id所有记录:

select * 
from xyz 
where exists (select * from xyz other where other.seq = xyz.seq and other.id < xyz.id); 
0

可以使用ROW_NUMBER解析函数:

SELECT ID, 
     PNO, 
     SEQ 
FROM (
    SELECT x.*, 
     ROW_NUMBER() OVER (PARTITION BY seq ORDER BY ID) AS rn 
    FROM XYZ 
) 
WHERE rn > 1 
0

的编程简单的方法是:

SELECT DISTINCT a.ID, a.PNO, a.SEQ 
FROM XYZ a 
JOIN XYZ b on a.SEQ = b.SEQ AND a.ID > b.ID 

这也只能选择重复。