如何根据一条记录上的失败标准消除所有分组记录

时间:2019-04-05 18:25:40

标签: sql-server

我经常遇到这样的问题:需要查询不仅要消除不符合条件的一条记录,还要消除基于其他分组的所有记录。例如,对于具有以下内容的表:

Name     ProdType   Prod   Spoiled     DateReceived  
Jack     Fruit      Apple   N          1/1/2019
Jack     Fruit      Pear    Y          1/1/2018
Jack     Fruit      Orange  N          1/1/2019
Jack     Vegetable  Okra    N          1/1/2019
Jack     Vegetable  Squash  N          1/1/2018
Jill     Fruit      Apple   N          4/1/2019
Jill     Fruit      Cherry  N          4/1/2019
Jill     Vegetable  Corn    Y          4/1/2019
Jill     Vegetable  Okra    N          4/1/2019

我的查询可能是要搜索谁拥有哪种水果,而没有损坏任何水果。

到目前为止,我一直在使用嵌套的select语句,但是随着我添加条件,它变得越来越困难。

SELECT NAME
    ,PRODTYPE
    ,PROD
    ,SPOILED
    ,DATEREC
FROM inventory
WHERE NAME in (
    SELECT DISTINCT Name from (SELECT Name FROM inventory
                WHERE ProdType = 'fruit' as Data)

    WHERE Name NOT IN (SELECT Name from inventory WHERE Name in (
            SELECT Name 
            WHERE Spoiled = 'Y'))
    )

在使用Jack和Jill的示例中,我的查询将为Jill返回2个结果(每个水果1个),而对于Jack则没有结果。

通常至少涉及两个表。添加条件时遇到问题(通常没有结果,或者甚至无法获得过去的错误来运行查询),例如,如果在X日期之前收到它被宠坏了就可以,并且添加其他表时

这种嵌套选择方式是创建列表然后搜索最佳方式还是SQL提供更好的东西?

谢谢。

2 个答案:

答案 0 :(得分:1)

不存在:

select i.* 
from inventory i
where 
  i.prodtype = 'Fruit' and
  not exists (
    select 1 from inventory
    where name = i.name and
    prodtype = 'Fruit' and
    spoiled = 'Y'
  )

答案 1 :(得分:1)

有很多创造性的方法可以用SQL表示查询。您的示例也可以通过这种方式实现,例如:

SELECT
    name,
    prodtype,
    prod,
    spoiled,
    daterec
FROM
    inventory
WHERE
    prodtype = 'Fruit' AND
    name NOT IN (SELECT name
                 FROM inventory
                 WHERE prodtype = 'Fruit' AND spoiled = 'Y')

要确定正确的(或至少是可以接受的)行驶方式,需要进行大量锻炼。而且对于某些数据请求通常没有“标准”解决方案。在某些情况下,如果单个需求发生变化而又不适合现有查询结构,则完全需要重新设计/重写查询。