当视图中已包含 where/filter 子句时,在选择视图上添加 where/filter 子句时会发生什么?

问题描述

我在视图中使用联合并过滤掉所有具有 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';

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

解决方法

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

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

sis'EQ'service_number 不是 'NECF' 以及 service_number'NECF' 但 {{1} 时保留一行}} 不是 sis。请注意,您使用了 EQ 运算符。如果要过滤掉 ORsis'EQ'service_number 的任何行,则需要使用 'NECF'

AND

另请注意,您可以使用德摩根定律轻松看出:
我们想过滤掉

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

这意味着我们希望保留其否定为真的行(在 sis = 'EQ' OR service_number = 'NECF' 子句中包含)。而否定是:

WHERE

即否定运算符并将 sis <> 'EQ' AND service_number <> 'NECF' 更改为 OR

同样有趣的是,您执行了相同集合的 AND -- 查询在语义上是相同的(不同的别名不会改变任何内容)。