在具有重复行的SQL server表中按组查找行号

在具有重复行的SQL server表中按组查找行号,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我需要在一个有一些重复的表中按组计算行号 表: id va1ue1 value2 1 3974 39 1 3974 39 1 972 5 1 972 10 SQL: 代码只对重复的行进行计数。 我需要: 我不需要计算重复的行,我只需要value1在value2列中有多个不同值的行 谢谢使用独特的: 如果您想要详细信息,那么: select * from table t1 cross apply(select cnt from(

我需要在一个有一些重复的表中按组计算行号

表:

id va1ue1 value2  
1   3974   39
1   3974   39
1   972    5
1   972    10
SQL:

代码只对重复的行进行计数。 我需要:

我不需要计算重复的行,我只需要value1在value2列中有多个不同值的行

谢谢

使用独特的:

如果您想要详细信息,那么:

select * from table t1
cross apply(select cnt from(
                            select count(distinct value2) cnt
                            from table t2 
                            where t1.id = t2.id and t1.value1 = t2.value1) t 
            where cnt > 1)ca
通过以下方式在没有分组的情况下进行尝试:

试试这个

;WITH    CTE
          AS ( SELECT   id ,
                        value1 ,
                        value2 ,
                        COUNT(*) cnt
               FROM     table
               GROUP BY id ,
                        value1 ,
                        value2
               HAVING   COUNT(*) > 1
             )
    SELECT  *
    FROM    table1
    WHERE   value1 IN ( SELECT  value1
                        FROM    CTE )

在SQLServer2008中,您可以使用一种技巧来使用窗口函数计算不同的值。您可能会发现这是一个很好的解决方案:

select t.id, t.value1, t.value2
from (select t.*, sum(case when seqnum = 1 then 1 else 0 end) over (partition by value1) as numvals
      from (select t.*, row_number() over (partition by value1, value2 order by (select null)) as seqnum
            from table t
           ) t
     ) t
where numvals > 1;
只需使用NOT after HAVE,它可以精确地获得不重复的行

 select id, value1, value2
 FROM [table]
 group by id, value1, value2
 having NOT COUNT(*)  > 1 

.

如果需要表中的实际行,而不仅仅是限定id、value1对,可以执行以下操作:

WITH discrepancies AS (
  SELECT,
    id,
    value1,
    value2,
    distinctcount = COUNT(DISTINCT value2) OVER (PARTITION BY id, value1)
  FROM
    dbo.atable
)
SELECT
  id,
  value1,
  value2
FROM
  discrepancies
WHERE
  distinctcount > 1
;
如果SQL Server 2008支持COUNTDISTINCT。。。带着一个

基本上,这将是相同的想法,或多或少,除了你不会击中表多次

唉,到目前为止还没有。尽管如此,您仍然可以使用另一种方法,该方法仍然允许您仅触摸表一次并返回详细信息行:

WITH discrepancies AS (
  SELECT,
    id,
    value1,
    value2,
    minvalue2 = MIN(value2) OVER (PARTITION BY id, value1),
    maxvalue2 = MAX(value2) OVER (PARTITION BY id, value1)
  FROM
    dbo.atable
)
SELECT
  id,
  value1,
  value2
FROM
  discrepancies
WHERE
  minvalue2 <> maxvalue2
;
这里的想法是为每个id value1获取MINvalue2和MAXvalue2,并查看它们是否不同。如果他们这样做了,这意味着您在这个id value1子集中有一个差异,您希望返回该行


该方法利用带有OVER子句的聚合来避免自联接,这正是表在此处仅被访问一次的原因。

在哪个版本中COUNTDISTINCT OVER fixed?@AndriyM。哎呀,我想到了甲骨文。
select t.id, t.value1, t.value2
from (select t.*, sum(case when seqnum = 1 then 1 else 0 end) over (partition by value1) as numvals
      from (select t.*, row_number() over (partition by value1, value2 order by (select null)) as seqnum
            from table t
           ) t
     ) t
where numvals > 1;
 select id, value1, value2
 FROM [table]
 group by id, value1, value2
 having NOT COUNT(*)  > 1 
WITH discrepancies AS (
  SELECT,
    id,
    value1,
    value2,
    distinctcount = COUNT(DISTINCT value2) OVER (PARTITION BY id, value1)
  FROM
    dbo.atable
)
SELECT
  id,
  value1,
  value2
FROM
  discrepancies
WHERE
  distinctcount > 1
;
WITH discrepancies AS (
  SELECT,
    id,
    value1,
    value2,
    minvalue2 = MIN(value2) OVER (PARTITION BY id, value1),
    maxvalue2 = MAX(value2) OVER (PARTITION BY id, value1)
  FROM
    dbo.atable
)
SELECT
  id,
  value1,
  value2
FROM
  discrepancies
WHERE
  minvalue2 <> maxvalue2
;