PostgreSQL查询优先级

时间:2011-09-29 09:22:55

标签: postgresql

在查询中,当我尝试在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_%'
       )

我不知道为什么...... ??????????

2 个答案:

答案 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)

它依赖于它的执行顺序,通常是从左到右。

你可以使用括号来解决这个问题。