sql查询获取除最小值之外的所有组号

时间:2017-09-10 19:31:44

标签: sql oracle

假设我有一个XYZ表,其中包含如下数据: -

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但排除SEQ的最小ID的行。输出应该是: -

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

我尝试使用下面的查询。它根据我的工作,但我需要优化它。请帮助降低成本。

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)

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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有一个相当不错的优化器,因此性能可能非常相似。

答案 2 :(得分:0)

您希望显示存在具有相同seq和较小id的其他记录的所有记录:

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

答案 3 :(得分: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

答案 4 :(得分:0)

以编程方式最简单的方法是:

index = this.props.applications[0]

这也只选择重复项。