【问题标题】:Select query to exclude group by column values选择查询以按列值排除分组
【发布时间】:2018-04-01 20:51:46
【问题描述】:

如何选择所有代码值不是 651、652、655、656 的所有记录作为唯一 ID。

包含 3 列的源表

ID Line Code
1 1 651
1 2 652
1 3 655
2 1 650
2 2 652
3 1 651
3 2 655
3 3 651
3 4 658
4 1 651
4 2 651

我想检索并非所有代码都是 ID 的 651/652/655/656 之一的所有记录

结果数据集如下所示

ID Line Code 
2 1 650 
2 2 652 
3 1 651 
3 2 655 
3 3 651 
3 4 658 

【问题讨论】:

    标签: sql sql-server-2005


    【解决方案1】:

    试试这个:

    SELECT t1.*
    FROM table1 as t1
    INNER JOIN
    (
      SELECT DISTINCT ID
      FROM table1 AS t1
      LEFT JOIN
      (
        SELECT 651 AS code UNION SELECT 652 UNION 
        SELECT 655 UNION SELECT 656
      ) AS t2 ON t1.code = t2.code
      WHERE t2.code is NULL
    ) AS t2 ON t1.id = t2.id;
    

    demo *(mysql 的演示,但对于 sql server 2005 仍然相同)

    | ID | Line | Code |
    |----|------|------|
    |  2 |    1 |  650 |
    |  2 |    2 |  652 |
    |  3 |    1 |  651 |
    |  3 |    2 |  655 |
    |  3 |    3 |  651 |
    |  3 |    4 |  658 |
    

    【讨论】:

    • 子查询中的条件聚合将是另一种选择
    • 好吧,对于任何未来的观众.. 这比它需要的复杂得多,主要是因为IN() 在 SQL Server 2005 中不可用的误导性概念正在流行这个问题。
    • @AaronDietz 在第一个版本中,我用 in 解决了它,但对于第一个评论,我将其更改为没有 in,但您是正确的,in 正常存在于 2005 年以及存在。感谢您指出。
    • @StephenParker 是的,我看到它发生了,我只怪文档造成了混乱。几年后,SQL Server 2005 将在新开发人员出生之前就已经发布了。我想知道有多少人会因为文档措辞而被困在使用它并且非常困惑...
    • @AaronDietz - 他们确实有 2005 年的单独文档,请参阅:technet.microsoft.com/en-us/library/ms177682(v=sql.90).aspx
    【解决方案2】:

    这是一个不使用 IN 或 Exists 的方法。它利用子查询中的条件聚合来确定每个 ID 是否存在比不需要的代码更多的记录,然后连接回原始表以获取更多详细信息。

    DECLARE @Table AS TABLE (ID int, Line INT, Code INT)
    
    INSERT INTO @Table (ID, Line, Code)
    VALUES (1, 1, 651),(1, 2, 652),(1, 3, 655),(2, 1, 650),(2, 2, 652)
           ,(3, 1, 651),(3, 2, 655),(3, 3, 651),(3, 4, 658),(4, 1, 651)
           ,(4, 2, 651)
    
    SELECT t1.*
    FROM
        @Table t1
        INNER JOIN (
           SELECT
              ID
           FROM
              @Table
           GROUP BY
              ID
           HAVING
              COUNT(*) > COUNT(CASE WHEN Code = 651 OR Code = 652 OR Code = 655 OR Code = 656 THEN Code END)) t2
        ON t1.ID = t2.ID
    

    【讨论】:

      【解决方案3】:

      您将检查是否存在代码,而不是这些值中的 lineitem。 这可以通过子查询来完成。例如:

      DECLARE @temp TABLE (ID int, Line int, Code int)
      INSERT INTO @temp VALUES
       (1, 1, 651),(1, 2, 652),(1, 3, 655),(2, 1, 650),(2, 2, 652),(3, 1, 651)
       ,(3, 2, 655),(3, 3, 651),(3, 4, 658),(4, 1, 651),(4, 2, 651)
      
      SELECT ID, Line, Code 
        FROM @temp T1
       WHERE EXISTS (SELECT *
                       FROM @temp T2
                      WHERE T2.ID = T1.ID
                        AND T2.Code NOT IN (651, 652, 655, 656)
                    )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-23
        • 2019-02-24
        • 1970-01-01
        相关资源
        最近更新 更多