Postgres查询包括时间范围

时间:2016-09-21 21:18:29

标签: postgresql

我有一个查询可以提取我需要跟踪的部分数据。我需要添加的是包含日期的列或查询表的日期范围的能力。如果可能的话,我更喜欢这个专栏。我使用的是psql 8.3.3。

以下是当前查询:

select count(mailing.mailing_id) as mailing_count, department.name as org 
from mailing, department 
where mailing.department_id = department.department_id 
group by department.name;

返回以下信息:

mailing_count  |                   org                   
---------------+-----------------------------------------
             2 | org1 name
             8 | org2 name
            22 | org3 name
            21 | org4 name
            39 | org5 name

我正在查询的表中有3列,其时间戳格式为target_launch_datecreated_timemodified_time

当我尝试将日期范围添加到查询时,我收到错误:

查询:

select count(mailing.mailing_id) as mailing_count, department.name as org 
from mailing, department 
where mailing.department_id = department.department_id 
group by department.name,
WHERE (target_launch_date)>= 2016-09-01 AND < 2016-09-05;

错误:

  

错误:“WHERE”第1行或附近的语法错误:   ... department.department_id group by department.name,WHERE(targ ...

我已经尝试在字符串中移动日期范围的位置以及各种其他更改,但无法实现我正在寻找的内容。

非常感谢任何见解!

2 个答案:

答案 0 :(得分:0)

这是一个可以满足您需求的查询:

SELECT 
  count(m.mailing_id) as mailing_count, 
  d.name as org 
FROM mailing m
JOIN department d USING( department_id )
WHERE 
  m.target_launch_date BETWEEN '2016-09-01' AND '2016-09-05'
GROUP BY 2

由于target_launch_date类型为timestamp,您可以安全地<= '2016-09-05'实际转换为2016-09-05 00:00:00.00000,为您提供当天开始之前的所有日期或完全2016-09-05 00:00:00.00000

其他一些注意事项:

  • 使用表名的别名来缩短代码,例如。 mailing m
  • 使用显式JOIN语法连接相关表格中的数据
  • WHERE之前应用GROUP BY条款,以排除与之不匹配的行
  • 使用BETWEEN运算符处理date >= X AND date <= Y案例
  • 当加入的列名相同时,您可以在JOIN语法中使用USING而不是ON
  • 您可以在GROUP BY中使用指向选择
  • 中列位置的列号

要更深入地了解SELECT语句的处理方式,请查看documentation

修改

使用BETWEEN运算符的方法会将2015-09-05 00:00:00.00000帐户设置为结果集。如果应该丢弃此时间戳,请将BETWEEN x AND y更改为这两个中的任何一个:

  • (...) BETWEEN x AND y::timestamp - INTERVAL '1 microsecond'
  • (...) >= x AND (...) < y

答案 1 :(得分:0)

你很接近,你需要在其他地方的第二部分提供列名称,你将只有一个地方:

select count(mailing.mailing_id) as mailing_count, department.name as org 
  from mailing 
  inner join department on mailing.department_id = department.department_id 
  where target_launch_date >= '2016-09-01'
    AND target_launch_date < '2016-09-05'
  group by department.name;

编辑:这部分仅适用于Kamil G.清楚地表明不应使用之间:

create table sample (id int, d timestamp);

insert into sample (id, d) 
values 
(1, '2016/09/01'),
(2, '2016/09/02'),
(3, '2016/09/03'),
(4, '2016/09/04'),
(5, '2016/09/05'),
(6, '2016/09/05 00:00:00'),
(7, '2016/09/05 00:00:01'),
(8, '2016/09/06');

select * from sample where d between '2016-09-01' and '2016-09-05';

结果:

1;"2016-09-01 00:00:00"
2;"2016-09-02 00:00:00"
3;"2016-09-03 00:00:00"
4;"2016-09-04 00:00:00"
5;"2016-09-05 00:00:00"
6;"2016-09-05 00:00:00"
顺便说一句,如果你在没有看到解释的情况下不相信,那么这就是:

  

过滤:((d> =&#39; 2016-09-01 00:00:00及#39; ::没有时区的时间戳)AND   (d&lt; =&#39; 2016-09-05 00:00:00&#39; ::没有时区的时间戳))