# 反转可返回UNKNOWN的布尔表达式

11

### 例

``````ID  myField
------------
1  someValue
2  NULL
3  someOtherValue``````

``````SELECT * FROM myTable WHERE myField = 'someValue'

-- yields record 1``````

``````SELECT * FROM myTable WHERE NOT (myField = 'someValue')

-- yields only record 3``````

``````SELECT * FROM myTable WHERE NOT (myField = 'someValue' AND myField IS NOT NULL)

-- yields records 2 and 3, hooray!``````

### 一般情况

``SELECT * FROM myTable WHERE ...some complex Boolean expression...``

``````SELECT * FROM myTable
WHERE ...some expression which stays...
AND ...some expression which I might want to invert...``````

15

``````SELECT
...
FROM
...
WHERE
CASE WHEN someColumn = someValue THEN 1 ELSE 0 END = 1
;``````

``````SELECT
...
FROM
...
WHERE
NOT CASE WHEN someColumn = someValue THEN 1 ELSE 0 END = 1
-- or: CASE WHEN someColumn = someValue THEN 1 ELSE 0 END <> 1
;``````

``CASE WHEN someColumn = someValue THEN 1 ELSE 0 END``

``IIF(someColumn = someValue, 1, 0)``

Heinzi

10

``````DECLARE @T AS table (c1 integer NULL);

INSERT @T (c1)
VALUES (1), (NULL), (2);

-- Original expression c1 = 1
SELECT T.c1
FROM @T AS T
WHERE c1 = 1;``````

``````-- Negated
SELECT T.c1
FROM @T AS T
WHERE NOT EXISTS (SELECT 1 WHERE c1 = 1);``````

``````sql = "
SELECT *
FROM someTable
WHERE " + someExpression +
" AND NOT EXISTS (SELECT 1 WHERE " +
someOtherExpression + ")";
result = executeAndShow(sql);``````

``````DECLARE @T AS table
(
c1 integer NULL,
c2 integer NULL,
c3 integer NULL
);

INSERT @T
(c1, c2, c3)
VALUES
(1, NULL, 2),
(2, 2, 3),
(NULL, 1, 4);``````

``````-- Original
SELECT
T.c1,
T.c2,
T.c3
FROM @T AS T
WHERE
1 = 1
-- Predicate #1
AND T.c1 = 2
-- Predicate #2
AND T.c2 =
(
SELECT MAX(T2.c2)
FROM @T AS T2
WHERE T2.c2 IS NOT NULL
)
-- Predicate #3
AND T.c3 IN (3, 4)
;

-- Invert predicates #1 and #2
SELECT
T.c1,
T.c2,
T.c3
FROM @T AS T
WHERE
1 = 1
AND NOT EXISTS (SELECT 1 WHERE 1 = 1
-- Predicate #1
AND T.c1 = 2)
AND NOT EXISTS (SELECT 1 WHERE 1 = 1
-- Predicate #2
AND T.c2 =
(
SELECT MAX(T2.c2)
FROM @T AS T2
WHERE T2.c2 IS NOT NULL
))
-- Predicate #3
AND T.c3 IN (3, 4)
;``````

3

``````SELECT *
FROM myTable
WHERE NOT (COALESCE(myField, 'notSomeValue') = 'someValue')``````

``````SELECT *
FROM myTable
WHERE NOT (
COALESCE(myField, 'notSomeValue') = 'someValue' AND
COALESCE(myField2, 'notSomeValue') = 'someValue2' AND
COALESCE(myField3, 'notSomeValue') = 'someValue3' AND
COALESCE(myField4, 'notSomeValue') = 'someValue4'
)``````

`COALESCE` 已记录为可从SQL Server 2005开始使用。

1
`COALESCE(myField, CONCAT('not', 'someValue')) = 'someValue'`应该适用于表中的所有“ someValue”和任何数据。
JimmyB

2

``````select * from table
except
select * from table
where <really complex predicates>``````

Lennart

-4

``SELECT * FROM myTable WHERE NOT COALESCE(myField = 'someValue', FALSE)``

4

Heinzi

@Heinzi-我确实尝试过，它起作用了，所以才发布了它。也许它在T-SQL上不起作用，但是在Postgres和MySQL上就可以了。

2
@Malvolio：问题标记了`sql-server`，但是不是`mysql``postgresql`
Andriy M

@Malvolio这是因为Postgres有一个`BOOLEAN`类型，而MySQL有一个（伪造的）`BOOLEAN`类型，它可以作为`COALESCE()`函数的参数。如果问题已用`sql-agnostic`或标记`sql-standard`，则可以。
ypercubeᵀᴹ

@ypercubeᵀᴹ-嗯，我能告诉你什么？获得更好的数据库。