在查询中,当我尝试在AND条件之前执行OR条件时,它会给出错误的结果..而web_filename_username_4hr_ts_201109也包含在内... 错误的结果查询:
SELECT tablename FROM pg_tables
WHERE schemaname = 'public'
and (tablename like 'web%_4hr_ts_%'
and tablename not like 'webs%_4hr_ts_%'
and tablename not like 'webr%_4hr_ts_%'
or tablename like '%web%summary%_4hr_ts_%'
and tablename not like 'web_filename_username%_4hr_ts_%'
)
;
但是当我在ORing之前执行所有AND时,它会给出正确的结果...... 正确的结果查询:
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
and (tablename like 'web%_4hr_ts_%'
and tablename not like 'webs%_12hr_ts_%'
and tablename not like 'webr%_4hr_ts_%'
and tablename not like 'web_filename_username%_4hr_ts_%'
or tablename like '%web%summary%_4hr_ts_%'
)
我不知道为什么...... ??????????
答案 0 :(得分:2)
因为您编写它的方式,它会检入块。
tablename like 'web%_4hr_ts_%'
and tablename not like 'webs%_4hr_ts_%'
and tablename not like 'webr%_4hr_ts_%'
或
tablename like '%web%summary%_4hr_ts_%'
and tablename not like 'web_filename_username%_4hr_ts_%'
现在很明显,tablename无法与'%web%summary%_4hr_ts_%'
和'web_filename_username%_4hr_ts_%'
匹配,因此总是会出错。
以下是关于它的解释
Nested Loop (cost=0.00..28.55 rows=1 width=64)
Join Filter: (c.relnamespace = n.oid)
-> Seq Scan on pg_class c (cost=0.00..27.45 rows=1 width=72)
Filter: ((relkind = 'r'::"char") AND (((relname ~~ 'web%_4hr_ts_%'::text) AND (relname !~~ 'webs%_4hr_ts_%'::text) AND (relname !~~ 'webr%_4hr_ts_%'::text)) OR ((relname ~~ '%web%summary%_4hr_ts_%'::text) AND (relname !~~ 'web_filename_username%_4hr_ts_%'::text))))
-> Seq Scan on pg_namespace n (cost=0.00..1.09 rows=1 width=4)
Filter: (n.nspname = 'public'::name)
正如您可以看到其添加的括号显示OR位于顶层。这就是为什么当我使用任何带有AND的OR时,我总是使用括号来确保正确的评估顺序。
如果你想知道为什么声明没有给你你想要的东西,只需在它面前解释,看看它会做什么。
答案 1 :(得分:0)
它依赖于它的执行顺序,通常是从左到右。
你可以使用括号来解决这个问题。