【问题标题】:How to use GROUP BY to identify row differences如何使用 GROUP BY 来识别行差异
【发布时间】:2015-05-28 17:46:09
【问题描述】:

我在 SQL Server 2008 中工作。我有以下情况。我有一个表,它有 2 列组成主键。 (不过,没有在键上定义唯一性约束。)我知道我有主键重复项。每个主键,我想识别另一列中的不同值。所以,假设我有下表:

INSERT INTO some_table (Col1, Col2, COl3) VALUES
('A', '1', 'a'),
('A', '1', 'b'),
('B', '1', 'a'),
('B', '2', 'b'),
('C', '1', 'a'),
('C', '1', 'a'),
('C', '2', 'b')

我想按 Col1 和 Col2 进行分组,并且我想找到所有有超过 1 个不同 Col3 值的行。例如,使用上表,我希望看到: (A, 1, a), (A, 1, b)。

如何编写这个 SQL 查询?我的 SELECT 语句需要包含 Col1、Col2 和 Col3。但是,如果我执行 GROUP BY Col1、Col2,那么我不能在 SELECT 语句中包含 Col3。

【问题讨论】:

  • 你不能有重复的主键,除非你的主键是合乎逻辑的。对主键强制执行唯一约束 100%,没有办法解决这个问题。我的猜测是您实际上没有在表中定义主键。
  • 你是对的。在我们的正式表中,它是主键。但是,在我们的数据验证表中,这只是合乎逻辑的。我的目标是对我们的数据验证表进行调查。

标签: sql-server


【解决方案1】:

您实际上不能在 group by 中为每个组选择多个项目,但也许您需要这样的东西:

select
  col1,
  col2,
  stuff((select ',' + col3 from some_table t2
   where t1.col1 = t2.col1 and t1.col2 = t2.col2
   FOR XML PATH ('')), 1, 1, '') as items
from
  some_table t1
group by
  col1,
  col2
having count(distinct col3) > 1

这将返回第三列中逗号分隔列表中的“重复”项目。

SQL Fiddle

【讨论】:

    【解决方案2】:

    这是解决此问题的一种方法:

    ;WITH CTE AS (
        Select col1, col2, min(col3) as minvalue, max(col3) as maxvalue
        From myTable
        Group by col1, col2
        Having min(col3) < max(col3)
    )
    
    Select * 
    From myTable t
    Inner join cte 
    On t.col1 = cte.col1
         And t.col2 = cte.col2
    Where col3 >= minvalue
    And col3 <= maxvalue
    

    注意代码直接写在这里,可能会有一些错误。

    【讨论】:

      【解决方案3】:

      试试这个:

          CREATE TABLE #some_table
          (
          Col1 char(1),
          Col2 char(1),
          Col3 char(1)
          )
      
          INSERT INTO #some_table (Col1, Col2, COl3) VALUES
          ('A', '1', 'a'),
          ('A', '1', 'b'),
          ('B', '1', 'a'),
          ('B', '2', 'b'),
          ('C', '1', 'a'),
          ('C', '1', 'a'),
          ('C', '2', 'b')
      
      
      
          select
            stuff((select ',' + '('+Col1 +', '+ Col2 + ', ' + Col3 + ')' from #some_table T_IN
             where T.col1 = T_IN.col1 and T.col2 = T_IN.col2 FOR XML PATH ('')), 1, 1, '') as items
          from
            #some_table T
          group by col1, col2
      

      【讨论】:

        【解决方案4】:

        这是到达那里的一种方式:

        SELECT *
        FROM
           T T1
        WHERE
            EXISTS(SELECT * FROM T T2
               WHERE 
                 T1.a = T2.a 
                 AND T1.b = T2.b
                 AND T1.c <> T2.c);
        

        sql fiddle

        或类似的变体,这将允许给出所需的最小不同数量:

        WHERE
        (SELECT COUNT(DISTINCT T2.c)
         FROM T T2
         WHERE T1.a = T2.a AND T1.b = T2.b) >= 2;
        

        sql fiddle

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-18
          • 1970-01-01
          • 2018-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多