如何在 PostgreSQL 中选择某一年之后的日期

Posted

技术标签:

【中文标题】如何在 PostgreSQL 中选择某一年之后的日期【英文标题】:How to choose dates after a certain year in PostgreSQL 【发布时间】:2015-02-04 23:56:10 【问题描述】:

简而言之,当我执行以下 SQL 命令时:

SELECT EXTRACT(YEAR FROM pub_date) AS year FROM news_stories

我得到了一份从 2008 年到 2014 年的大名单。

如果我这样做了

SELECT EXTRACT(YEAR FROM pub_date) AS year FROM news_stories WHERE year > 2010

我得到一个空的结果。我做错了什么?

【问题讨论】:

【参考方案1】:

输出列在ORDER BYGROUP BY 子句中可见,因为它们是在SELECT 子句中评估表达式之后应用的。它们在 WHEREHAVING 子句中不可见。所以你不能引用 output 列名year。您必须根据 input 列重复表达式。显然,有一个同名的输入列,否则你会得到一个异常。详情:

How to re-use result for SELECT, WHERE and ORDER BY clauses?

为了让您的查询快速,您应该使用 sargable 谓词:

SELECT EXTRACT(YEAR FROM pub_date) AS year
FROM   news_stories
WHERE  pub_date >= '2010-1-1'::date;

这通常更快,因为 Postgres 可以直接将 pub_date 中的值与给定值进行比较,而无需先从每一行中提取年份。 更重要的是,可以通过这种方式使用 pub_date 上的普通索引 - 如果 Postgres 期望该路由更快(仅索引扫描或足够选择性)。

【讨论】:

所以我从中得到的 tl;dr 是 "WHERE pub_date >= '2010-1-1'::date" 比 "WHERE EXTRACT(YEAR FROM pub_date) > 2010" 快吗?我刚刚做了一些 AB 速度测试,并没有看到任何变化(脚本在任何一种情况下都需要 3-5 秒才能运行)……但如果你说最好采用 sargable 方法,我很好。 :-) 谢谢! @DanGoodspeed:当您选择表的一小部分或 pg 可以使用仅索引扫描 (example )。当必须读取表的大部分内容时,pg 将使用顺序扫描,您几乎看不出有什么不同。无论哪种方式,3-5 秒似乎非常长。你的桌子很大吗?你如何测量?你的pg是什么版本?我会使用EXPLAIN ANALYZE 进行测试。您不想在测试中包含网络开销。 这是一个非常不科学的测试。这是一个 perl 脚本,它执行一些通过网络运行的数据库调用(这是其中之一),我只是为页面加载计时。【参考方案2】:

您必须在数据库中有一个名为year 的列,否则SQL 将返回错误。您不能在定义别名的selectwhere 子句中使用别名。

要么使用子查询,要么重复表达式:

SELECT EXTRACT(YEAR FROM pub_date) AS year
FROM news_stories
WHERE EXTRACT(YEAR FROM pub_date) > 2010;

或作为子查询:

select *
from (SELECT EXTRACT(YEAR FROM pub_date) AS year
      FROM news_stories
     ) n
where year > 2010;

【讨论】:

【参考方案3】:

试试这个。您不能在 where 子句中使用alias namein。 WHERE clauseSELECT clause(*) 之前处理。由于您有名为 Year 的列,因此您没有收到错误。

SELECT EXTRACT(YEAR FROM pub_date) AS year 
FROM news_stories 
WHERE EXTRACT(YEAR FROM pub_date) > 2010

【讨论】:

谢谢。我认为 AS 的主要目的之一是能够缩短其中一些 SQL 语句,就像我编写它的方式一样。 @DanGoodspeed ALIASES 可用于为列或表创建一个临时名称。如果您想在where Clause 中使用别名,请查看 Gordan 答案。

以上是关于如何在 PostgreSQL 中选择某一年之后的日期的主要内容,如果未能解决你的问题,请参考以下文章

选择某一年之前的最大日期

取上个月和上一年的数据,sql怎么写

MySQL中, 如何查询某一天, 某一月, 某一年的数据.

如何在postgresql中使用CASE和Between in where条件一年

C语言程序设计判断某一年是不是是闰年

如何使用 mapreduce 和 pyspark 查找某一年某一天的频率