就在最近,我在博客中发布了有关PostgreSQL 9.3的信息 ,这真是太棒了,因为PostgreSQL最终支持物化视图和可更新视图。 然后,我在博客上发表了有关PostgreSQL语法的奥秘,只有它的强大功能才能解决,因为与RETURNING子句一起使用时,它允许将INSERT和UPDATE语句视为表引用。 即使在日常SQL中不是很有用,这也很不错。
但是我今天所写的内容非常庞大:
PostgreSQL谓词只是普通表达式
让我们沉浸其中。对于PostgreSQL,谓词只是评估布尔类型的普通表达式。 SELECT语法参考中对此进行了说明, 网址为 : http : //www.postgresql.org/docs/9.3/static/sql-select.html
引用:
可选的
WHERE
子句具有一般形式
WHERE condition
condition
是任何计算结果为boolean
型[…]的表达式
当我读到这个Stack Overflow问题时,它像闪电一样轰动我。 您可以在任何地方放置谓词! 尽管我以前知道这一点,但我从未想过这有多棒! 您可以在SELECT子句中使用谓词:
SELECT a, b, c = d, e IN (SELECT x FROM y)
FROM t
您可以在GROUP BY子句中使用谓词:
SELECT count(*)
FROM t
GROUP BY c = d, e IN (SELECT x FROM y)
您可以在ORDER BY子句中使用谓词:
SELECT *
FROM t
ORDER BY c = d, e IN (SELECT x FROM y)
您可以使用EVERY聚合函数来聚合谓词。
不相信吗? 在此SQLFiddle中自己看看 !
“普通” SQL
在“普通” SQL(即符合标准)中,必须使用CASE子句将谓词转换为普通值表达式。 重复以上示例:
SELECT子句:
SELECT a, b,
CASE WHEN c = d THEN true ELSE false END,
CASE WHEN e IN (SELECT x FROM y)
THEN true ELSE false END
FROM t
GROUP BY子句:
SELECT count(*)
FROM t
GROUP BY CASE WHEN c = d THEN true ELSE false END,
CASE WHEN e IN (SELECT x FROM y)
THEN true ELSE false END
ORDER BY子句:
SELECT *
FROM t
ORDER BY CASE WHEN c = d THEN true ELSE false END,
CASE WHEN e IN (SELECT x FROM y)
THEN true ELSE false END
对jOOQ的影响
上面的堆栈溢出问题中给出的答案显示了jOOQ如何通过将谓词/条件直接呈现为受支持的列表达式来标准化该行为,同时使用等效的CASE表达式来模拟该行为。
以SELECT子句中的谓词为例:
DSL.using(configuration)
.select(
T.A, T.B,
// Transform a jOOQ Condition into a Field:
field(T.C.eq(T.D)),
field(T.E.in(select(Y.X).from(Y)))
)
.from(T);
进一步的想法
从jOOQ集成测试的经验来看,我可以说Derby,H2,HSQLDB,MariaDB,MySQL,PostgreSQL和SQLite将以这种方式工作。 尽管从语法角度来看这很棒,但请密切注意您的执行计划,以确保它不会产生很多非常昂贵的嵌套循环……
翻译自: https://www.javacodegeeks.com/2013/09/why-postgresql-is-so-awesome.html