【问题标题】:Find Records With No Matching Criteria查找没有匹配条件的记录
【发布时间】:2013-04-23 13:48:43
【问题描述】:

我知道这个标题是模棱两可的,这个问题可能以前被问过,但我不知道如何总结我的问题以便能够搜索它或写一个更好的标题!这可能很简单,但它不断出现,我无法理解它。所以这里有一个例子:

假设我有这张桌子Lunch

如果我想查询所有午餐吃苹果的人,这很简单,我只需使用

SELECT [Name] FROM [Lunch] WHERE [Lunch Item] = 'Apple' GROUP BY [Name]

但是,如果我想获得一份午餐没有苹果的人的名单,该怎么办?如果我使用

SELECT [Name] FROM [Lunch] WHERE [Lunch Item] <> 'Apple' GROUP BY [Name]

结果仍将包括确实有苹果的人,因为他们也有其他不是苹果的东西。

正如我所说,我觉得这一定是一个简单的查询,但我不知道语法是什么。

【问题讨论】:

    标签: sql sql-server tsql group-by


    【解决方案1】:

    我更喜欢使用聚合来解决这些问题:

    select [name]
    from lunch
    group by name
    having sum(case when [lunch item] = 'Apple' then 1 else 0 end) = 0;
    

    这种结构是相当通用的。如果你想要一个有苹果和葡萄但没有橙子的人,你可以这样做:

    select [name]
    from lunch
    group by name
    having sum(case when [lunch item] = 'Apple' then 1 else 0 end) > 0 and
           sum(case when [lunch item] = 'Oranges' then 1 else 0 end) > 0 and
           sum(case when [lunch item] = 'Grapes' then 1 else 0 end) = 0
    

    【讨论】:

    • 由于某种原因,我无法让它工作。我理解它背后的原理,但是当我尝试在 SELECT 语句中使用 COUNT 或在 CASE 子句中使用 LIKE 时,它似乎会破坏它。例如,我将如何调整它以返回没有包含字母“pple”的午餐项目的人数?
    • 不,我收回。我可以让您的第一个示例工作,但如果我将 SELECT 语句更改为 SELECT COUNT,它会返回 NULL。无法想象为什么!
    【解决方案2】:

    如果你有一张供人使用的桌子:

    SELECT  *
    FROM    people
    WHERE   name NOT IN
            (
            SELECT  name
            FROM    lunch
            WHERE   lunchItem = 'apple'
            )
    

    如果你不这样做:

    SELECT  name
    FROM    lunch
    EXCEPT
    SELECT  name
    FROM    lunch
    WHERE   lunchItem = 'apple'
    

    【讨论】:

    • 这不应该是 SELECT DISTINCT 名称吗?还是会 EXCEPT 删除第一个查询中的重复项?
    • 我的实际场景确实涉及两个表,第一个示例看起来正是我所需要的,只是我无法让它工作。查询解析成功,但没有返回结果。
    • @FrankSchmitt: EXCEPT 删除重复项
    • @PhilipStratford:可能你模型中的人喜欢苹果?
    【解决方案3】:

    如果您想使用 group by 子句,请使用类似的内容。如果您只想要人员列表,还有许多其他方法。

    SELECT [Name]
    FROM [Lunch]
    GROUP BY [Name]
    HAVING SUM(CASE WHEN [Lunch Item] = 'Apple' then 1 else 0 end) = 0 --people who had a total amount of 0 apples for lunch
    

    【讨论】:

      【解决方案4】:

      这是第三种方法,因为为什么不呢!

      SELECT DISTINCT Name 
      FROM Lunch L
      WHERE NOT EXISTS (SELECT 1 FROM Lunch WHERE Name = L.Name AND [Lunch Item] = 'Apple')
      

      【讨论】:

        【解决方案5】:

        使用NOT EXISTS 方法

        SELECT  *
        FROM    Lunch a
        WHERE   NOT EXISTS
        (
            SELECT  1
            FROM    Lunch b
            WHERE   a.Name = b.Name AND
                    b.Item = 'Apple'
        )
        

        【讨论】:

          【解决方案6】:

          使用NOT IN 运算符排除所有拥有苹果的人。

          SELECT * FROM Lunch
          WHERE Name NOT IN ( SELECT Name
                              FROM Lunch
                              WHERE LunchItem ="Apple"
                             )
          

          我认为不需要GROUP BY 子句。

          【讨论】:

            猜你喜欢
            • 2016-11-13
            • 2012-07-31
            • 1970-01-01
            • 2016-03-30
            • 2013-09-27
            • 1970-01-01
            • 1970-01-01
            • 2023-02-22
            • 1970-01-01
            相关资源
            最近更新 更多