仅选择具有重复行的那些

时间:2018-02-28 17:44:13

标签: sql sql-server tsql

我试图查找具有相同fnumberfname

的行

我可以使用此查询返回重复的内容,但它只给出了重复项。我想要返回重复行和原始行。

WITH CTE AS(
   SELECT fnumber, findex,fname,
       RN = ROW_NUMBER()OVER(PARTITION BY fnumber ORDER BY fnumber)
   FROM dbo.coolTableBro
   where fnumber like '014%'
)
select * FROM CTE where RN > 1

查询输出:

fnumber findex  fname   RN
01474   220569  MT1     2
01475   220570  MT1     2
01476   220571  MT1     2
01477   220572  MT1     2
01478   220573  MT1     2
01479   220574  MT1     2
01480   220575  MT1     2
01481   220576  MT1     2

期望的输出:

fnumber findex  fname   RN
01474   220532  MT1     1
01474   220569  MT1     2
01475   220533  MT1     1
01475   220570  MT1     2
01476   220534  MT1     1
01476   220571  MT1     2
01477   220535  MT1     1
01477   220572  MT1     2
01478   220536  MT1     1
01478   220573  MT1     2
01479   220537  MT1     1
01479   220574  MT1     2
01480   220538  MT1     1
01480   220575  MT1     2
01481   220539  MT1     1
01481   220576  MT1     2

如果我更改where子句,我也会得到几行不重复的行。我需要像这样的伪语句,这显然不是有效的SQL

select fnumber,findex,fname from coolTableBro where fnumber and fname are the same in at least two rows and fnumber starts with 014

2 个答案:

答案 0 :(得分:2)

您可以使用COUNT

WITH CTE AS(
   SELECT fnumber, findex,fname,
       RN = ROW_NUMBER()OVER(PARTITION BY fnumber ORDER BY fnumber),
       CNT = COUNT(*) OVER (PARTITION BY fnumber)
   FROM dbo.coolTableBro
   where fnumber like '014%'
)
select * FROM CTE where CNT > 1;

答案 1 :(得分:0)

一种方法使用count(*)代替row_number()

with cte as (
      select fnumber, findex, fname,
             count(*) over (partition by fnumber) as cnt
      from dbo.coolTableBro
      where fnumber like '014%'
)
select * 
from cte
where cnt > 1;

就绩效而言,exists往往更好:

select tb.*
from dbo.coolTableBro tb
where tb.fnumber like '014%' and
      exists (select 1
              from dbo.coolTableBro tb2
              where tb2.fnumber = tb.fnumber and tb2.findex <> tb.findex
             );

如果您在(fnumber, findex)上有索引,则尤其如此。