【问题标题】:Extract year from date within WHERE clause从 WHERE 子句中的日期提取年份
【发布时间】:2014-12-12 09:42:07
【问题描述】:

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

SELECT * FROM my_table WHERE EXTRACT(YEAR FROM date) = '2014';

我收到这样的消息:

pg_catalog.date_part(unknown, text) doesn't exist** 
SQL State 42883

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

  gid  |    date
-------+-------------
  1    | 2014-12-12
  2    | 2014-12-08
  3    | 2013-17-15

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

【问题讨论】:

  • 那么问题是什么?它没有按您的预期工作吗?这会产生错误消息吗?
  • 我更新了消息。确实有报错信息...
  • 这个查询在我的机器上运行良好。您使用的是什么版本的 postgres?
  • PostgreSQL 9.2.2,由 Visual C++ build 1600 编译,32 位
  • 字段“日期”的正常索引无助于提高性能。使用相同的 EXTRACT() 定义来创建函数索引或在 WHERE 中使用 BETWEEN 条件而不是 EXTRACT 条件。

标签: postgresql date types where-clause


【解决方案1】:

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

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

ALTER TABLE my_table ALTER COLUMN date TYPE date;

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

此外,为了使您的查询使用普通索引快速date 上,您应该使用sargable 谓词。喜欢:

SELECT * FROM my_table
WHERE    date >= '2014-01-01'
AND      date <  '2015-01-01';

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

SELECT * FROM my_table
WHERE    date >= to_date('2014', 'YYYY')
AND      date <  to_date('2015', 'YYYY');

你也可以更明确:

to_date('2014' || '0101', 'YYYYMMNDD')

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

旁白:date 是标准 SQL 中的 reserved word 和 Postgres 中的基本类型名称。不要将其用作标识符。

【讨论】:

    【解决方案2】:

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

    SELECT 1 WHERE extract(year from '2014-01-01'::text)='2014';
    

    产生此错误:

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

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

    SELECT * FROM my_table WHERE left(date,4)='2014';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 1970-01-01
      • 2013-03-05
      • 2021-10-02
      相关资源
      最近更新 更多