从WHERE子句中的日期中提取年份

wil*_*map 3 postgresql types date where-clause

我需要EXTRACT()WHERE子句中包含函数,如下所示:

SELECT * FROM my_table WHERE EXTRACT(YEAR FROM date) = '2014';
Run Code Online (Sandbox Code Playgroud)

我收到这样的消息:

pg_catalog.date_part(unknown, text) doesn't exist** 
SQL State 42883
Run Code Online (Sandbox Code Playgroud)

这是my_table内容(gid INTEGER, date DATE):

  gid  |    date
-------+-------------
  1    | 2014-12-12
  2    | 2014-12-08
  3    | 2013-17-15
Run Code Online (Sandbox Code Playgroud)

我必须这样做,因为查询是从网站上包含“年份”字段的网站上的表单发送的,用户在其中输入4位数字的年份。

Erw*_*ter 6

问题是您的列属于数据类型 text,而EXTRACT()仅适用于date/ time类型

您应该将列转换为适当的数据类型。

ALTER TABLE my_table ALTER COLUMN date TYPE date;
Run Code Online (Sandbox Code Playgroud)

它更小(4个字节,而不是文本的11个字节),更快更干净(不允许非法日期和大多数错字)。
如果您使用非标准格式,请添加USING带有转换表达式的子句。例:

另外,为了使查询快速使用纯索引date您应该使用可修饰的谓词。喜欢:

SELECT * FROM my_table
WHERE    date >= '2014-01-01'
AND      date <  '2015-01-01';
Run Code Online (Sandbox Code Playgroud)

或者,使用年份的4位数输入:

SELECT * FROM my_table
WHERE    date >= to_date('2014', 'YYYY')
AND      date <  to_date('2015', 'YYYY');
Run Code Online (Sandbox Code Playgroud)

您也可以更加明确:

to_date('2014' || '0101', 'YYYYMMNDD')
Run Code Online (Sandbox Code Playgroud)

两者产生相同的日期'2014-01-01'

除了:在标准SQL中date保留字,在Postgres中是基本类型名。不要将其用作标识符。


Dan*_*ité 3

发生这种情况是因为该列具有 text 或 varchar 类型,而不是datetimestamp。这很容易重现:

SELECT 1 WHERE extract(year from '2014-01-01'::text)='2014';
Run Code Online (Sandbox Code Playgroud)

产生这个错误:

错误:函数 pg_catalog.date_part(unknown, text) 不存在
第 1 行:SELECT 1 WHERE extract(year from '2014-01-01'::text)='2014';
^ 提示:没有函数与给定名称和参数类型匹配。您可能需要添加显式类型转换。

extractor 是date_part类似文本数据类型的基础函数不存在,但无论如何都不需要它们。从该日期格式中提取年份相当于获取前 4 个字符,因此您的查询将是:

SELECT * FROM my_table WHERE left(date,4)='2014';
Run Code Online (Sandbox Code Playgroud)