假设我有一个名为 MyTable 的表,其时间戳字段为“已创建”。我只想提取本专栏的日期部分,在我的研究中我发现了这些替代方案:
SELECT created AS "Original",
date(created) AS "DateFunction",
created::date AS "DoubleColonCast",
cast(created as date) AS "CastFunction",
date_trunc('day', created) AS "DateTrunc"
FROM MyTable
- 就SARGability 而言,首选方法是什么?
- 什么是“SQL ANSI”(即更便携)方式?
- Postgres 中最常见/最常用的是什么?
正如其他人指出的那样
date(created)
,created::date
并且cast(created as date)
在功能上是等效的。如果您想要便携,请使用
cast()
. 我认为::
运算符在“Postgres 土地”中更常见。但是,date_trunc('day', created)
不等价于其他表达式,因为它返回一个值,而不是a。timestamp
date
这些表达式都不会使用索引
created
- 您需要使用查询中使用的表达式创建基于表达式的索引。该cast()
表达式将被::
查询优化器重写,而date(...)
不会。因此,如果您创建基于表达式的索引,使用cast()
或::
不会在索引表达式和查询中使用的表达式之间产生差异。但是,如果您使用
date(..)
ordate_trunc()
您将不得不在查询中使用相同的表达式来使用索引。created::date
并且cast(created as date)
在语法上是等效的,但cast(created as date)
将是它们中最便携的,因为它最接近 ANSI SQL。我不相信它们中的任何一个都是SARGable,但
date_trunc('day', created)
可能会导致发生额外的强制转换操作以在应用它的逻辑之前将日期值转换为时间戳,所以在所有这些中,你最好的选择是使用cast(created as date)
.所有这些形式都同样好。
如果这些表达式中的任何一个出现在像这样的
WHERE
子句中那么您必须使用完全相同的表达式创建索引: