简体   繁体   English

基于其他行排除行(SQL)

[英]Exclude rows based on other rows (SQL)

Say I have a query like this: 说我有这样的查询:

SELECT *
FROM TABLE

And it returns this: 它返回:

TABLE
ID | DATA | VAL
===============
01 | ABCD | 1
01 | DEFG | 2
02 | FGHI | 3
02 | HIJK | 2
03 | JKLM | 3
03 | LMNO | 4
04 | NOPQ | 0
04 | PQRS | 1

Currently I have a query that attempts find only good values like this, but it's flawed because IDs that have bad VALs in other rows are included, which is not what I'd like. 目前我有一个查询尝试只找到这样的好值,但它有缺陷,因为包含其他行中的VAL不好的ID,这不是我想要的。

SELECT *
FROM TABLE
WHERE TABLE.VAL IN ("1","2","3")

would return this (with LMNO and PQRS missing): 将返回此(缺少LMNO和PQRS):

TABLE
ID | DATA | VAL
===============
01 | ABCD | 1
01 | DEFG | 2
02 | FGHI | 3
02 | HIJK | 2
03 | JKLM | 3
04 | NOPQ | 0

However, I only want rows where the ID has NO bad values. 但是,我只想要ID没有错误值的行。 So, 01 and 02 are fine because all of their rows have good results. 所以,01和02都很好,因为它们的所有行都有很好的结果。 03 and 04 are bad because they're tainted by the bad results in other rows. 03和04很糟糕,因为它们被其他行中的坏结果所污染。

I could just bring the result in like this and process it that way in software, but it seems as though this should be possible with a database, and as a general rule, doing it on the database is better than in software (you know, that's kind of what they're there for...) 我可以像这样把结果带进去并在软件中以这种方式处理,但似乎这对数据库来说应该是可能的,并且作为一般规则,在数据库上执行它比在软件中更好(你知道,这就是他们的目的......)

The best I could come up with is this: 我能想到的最好的是:

SELECT *
FROM TABLE
WHERE COUNT( SELECT ID
             FROM TABLE
             WHERE TABLE.VAL NOT IN ("1","2","3")
           ) = 0

Is this viable? 这可行吗? Is there a better alternative? 还有更好的选择吗?

Thanks! 谢谢!

Use: 采用:

SELECT * 
  FROM TABLE a
 WHERE a.val IN (1,2,3)
   AND NOT EXISTS(SELECT NULL
                    FROM TABLE b
                   WHERE b.id = a.id
                     AND b.val NOT IN (1, 2, 3))

you could use a minus operator. 你可以使用减号运算符。

pseudo-query 伪查询

select everything
from tables
where id in ( select id from table minus select id from table where val is bad )

you could try something like 你可以试试像

SELECT *
FROM TABLE
WHERE TABLE.ID NOT IN(
    SELECT ID
    FROM TABLE
    WHERE TABLE.VAL < '1'
    OR TABLE.VAL > '3'
)

Here is another alternative that will pass through TBL once, aggregate, and using the IDs found, retrieve the data from TBL 这是另一种替代方案,它将通过TBL一次,聚合,并使用找到的ID,从TBL中检索数据

SELECT *
WHERE ID IN
(
    SELECT
       ID,
       CASE WHEN val in (1,2,3) THEN 1 ELSE 0 END Test
    FROM TBL
    GROUP BY ID
    HAVING MIN(val) = 1
)

For multi-column keys, and as an alternative to the above IN form, you can use the JOIN form. 对于多列键,作为上述IN表单的替代,您可以使用JOIN表单。

SELECT T.*
FROM (
    SELECT
       Company, OrderNumber,
       CASE WHEN val in (1,2,3) THEN 1 ELSE 0 END Test
    FROM TBL
    GROUP BY Company, OrderNumber
    HAVING MIN(val) = 1
    ) KEEP
INNER JOIN TBL T ON T.Company = KEEP.Company and T.OrderNumber=KEEP.OrderNumber

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM