【问题标题】:find row number by group in SQL server table with duplicated rows在具有重复行的 SQL Server 表中按组查找行号
【发布时间】:2015-05-18 22:16:50
【问题描述】:

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

表:

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

SQL:

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

代码只计算重复的行。 我需要:

 id, value1, value2
 1   972      5      
 1   972      10     

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

谢谢

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    使用DISTINCT:

    select id, value1, count(distinct value2) cnt
    from table
    group by id, value1
    having count(distinct value2)  > 1 
    

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

    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
    

    【讨论】:

      【解决方案2】:

      在 SQL Server 2008 中,您可以使用一种技巧来使用窗口函数对不同的值进行计数。您可能会发现这是一个不错的解决方案:

      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;
      

      【讨论】:

      • COUNT(DISTINCT) OVER 是在哪个版本中修复的?
      • @AndriyM 。 . .糟糕,我在考虑 Oracle。
      【解决方案3】:

      在没有GROUP BY 的情况下尝试这种方式:

       select id, value1, value2
       FROM table AS T1
       where 1 < (
         select  COUNT(*) 
         FROM table AS T2
         where T1.value1 = T2.value1)
      

      【讨论】:

        【解决方案4】:

        试试这个

        ;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 )
        

        【讨论】:

          【解决方案5】:

          只需在HAVING 之后使用NOT,即可准确获取不重复的行。

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

          Fiddle here.

          【讨论】:

            【解决方案6】:

            如果您想要表中的实际行,而不仅仅是符合条件的 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 支持 COUNT(DISTINCT ...)OVER clause

            基本上,这与Giorgi Nakeuri's one 的想法差不多,只是你不会多次上桌。

            唉,到目前为止还有no support for COUNT(DISTINCT ...) OVER ... in SQL Server。不过,您可以使用不同的方法,它仍然允许您只触摸一次表格并返回详细信息行:

            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 获得MIN(value2)MAX(value2) 并查看它们是否不同。如果是这样,则意味着您在此 id, value1 子集中存在差异,并且您希望返回该行。

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

            【讨论】:

              猜你喜欢
              • 2023-03-31
              • 2021-03-01
              • 2020-07-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多