0

我在视图中使用联合并过滤掉所有具有EQNECF如下所示的项目:

REPLACE VIEW X.VIEW_NAME
AS
LOCKING ROW FOR ACCESS
SELECT
*
FROM X.TABLENAME A
WHERE A.SIS <> 'EQ' OR A.SERVICE_NUMBER <> 'NECF'
UNION ALL
SELECT
*
FROM X.TABLENAME B
WHERE B.SIS <> 'EQ' OR B.SERVICE_NUMBER <> 'NECF';

现在,如果我再次过滤视图

SEL *
FROM X.VIEWNAME A
WHERE A.SIS = 'EQ' OR A.SERVICE_NUMBER = 'NECF';

我确实有记录!视图不应该过滤掉EQor NECF。当我对视图进行第二次选择查询时,我应该收到 0 条记录?

4

1 回答 1

2

您的视图包含您预期的另一个视图。

...
WHERE A.SIS <> 'EQ'
       OR A.SERVICE_NUMBER <> 'NECF'
...

保留一行 when sisis 'EQ'but service_numberis not'NECF'以及 when service_numberis 'NECF'but sisis not EQ。请注意,您使用了OR运算符。如果要过滤掉sisis'EQ'service_numberis的任何行,则'NECF'需要使用AND

...
WHERE A.SIS <> 'EQ'
      AND A.SERVICE_NUMBER <> 'NECF'
...

另请注意,您可以通过使用德摩根定律轻松地看到这一点:
我们想要过滤掉

sis = 'EQ'
 OR service_number = 'NECF'

这意味着我们希望保留否定为真的行(在WHERE子句中包含它)。否定是:

sis <> 'EQ'
 AND service_number <> 'NECF'

那就是否定运算符并更改 ORAND.

同样有趣的是,您执行的UNION ALL是同一组的查询——从语义上讲,查询是相同的(不同的别名没有任何变化)。

于 2021-07-08T20:16:57.913 回答