SQL WHERE 子句从多个列中过滤

SQL WHERE clause filter from more than one column

我有一个 table:

RowID      QuestionNum   Survey
--------------------------------
ABC          1             1
DEF          2             1
ASD          3             1
RDS          4             1
TGH          5             1
YHG          1             2
TGF          2             2
UHJ          3             2
UJH          4             2
IJK          5             2
UJH          6             2

RowID 为字符串,QuestionNum 和 Survey 为 INT。

我只想排除:

这是我的 SQL:

SELECT RowID, QuestionNum, SurveyType
FROM dbo.tblTest
WHERE (SurveyType <> 1) 
  AND (QuestionNum <> 5) 
   OR (SurveyType <> 2) AND (QuestionNum <> 6)

但是 returns 所有行 - 我错过了什么?

谢谢。

All I want to do is exclude QuestionNum 1 and Survey 1 AND QuestionNum 6 and Survey 2

您可以将此条件表述为:

WHERE NOT (
    (SurveyType = 1 AND QuestionNum = 5) 
    OR (SurveyType = 2 AND QuestionNum = 6)
)

我总是无法解释 SQL 上的 NOT(...) 条件,所以我选择了积极的方式:

SELECT
    RowID, 
    QuestionNum, 
    SurveyType
FROM
    dbo.tblTest
WHERE
    (
        QuestionNum <> 1 OR                     -- Either question number isn't 1
        (QuestionNum = 1 AND SurveyType <> 1)   -- ... or if it is 1, then survey type mustn't be 1
    ) 
    AND
    (
        QuestionNum <> 6 OR                     -- Either question number isn't 6
        (QuestionNum = 6 AND SurveyType <> 2)   -- ... or if it is 6, then survey type musn't be 2
    )

将不得不注意 NULL 值,如果它们可能出现在您的列中。如果要排除一堆行,请阅读 Salman 的解决方案。

如果配对列表太大,您可以使用基于集合的方法:

SELECT RowID, QuestionNum, Survey
FROM t
WHERE NOT EXISTS (
    SELECT 1
    FROM (VALUES
        (1, 1),
        (6, 2)
        -- add moar pairs
    ) AS e(QuestionNum, Survey)
    WHERE t.QuestionNum = e.QuestionNum AND t.Survey = e.Survey
)

Demo on db<>fiddle

将您的要求转换为查询时,这是运算符优先级的问题, 排除:

QuestionNum 1 and Survey 1
QuestionNum 6 and Survey 2

:以下内容应该适用于您的情况:

SELECT RowID, QuestionNum, SurveyType
FROM dbo.tblTest
WHERE (SurveyType <> 1 AND QuestionNum <> 1) 
   OR (SurveyType <> 2 AND QuestionNum <> 6)