问题描述
我在视图中使用联合并过滤掉所有具有 EQ
或 NECF
的项目,如下所示:
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';
我确实得到了记录!视图不应该过滤掉 EQ
或 NECF
。当我对视图进行第二次选择查询时,我应该收到 0 条记录?
解决方法
您的视图包含另一个超出您预期的视图。
...
WHERE A.SIS <> 'EQ'
OR A.SERVICE_NUMBER <> 'NECF'
...
在 sis
是 'EQ'
但 service_number
不是 'NECF'
以及 service_number
是 'NECF'
但 {{1} 时保留一行}} 不是 sis
。请注意,您使用了 EQ
运算符。如果要过滤掉 OR
为 sis
或 '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
-- 查询在语义上是相同的(不同的别名不会改变任何内容)。