从具有创建日期的表中获取上周的数据

时间:2017-01-18 08:19:00

标签: sql postgresql

使用以下查询检索上周数据,但我收到错误

  

Postgres ERROR:语法错误在或接近" CAST"位置:127

我不知道错误的位置:

ImageMagic

2 个答案:

答案 0 :(得分:3)

你太复杂了。要获得上周的数据,只需在“本周开始”减去7天后获取所有内容:

可以使用date_trunc('week', current_date)评估“本周开始”。

如果您减去7天,则会获得前一周的开始date_trunc('week', current_date) - interval '7' day。如果您减去1天,则会获得前一周的结束

date_trunc总是使用星期一作为一周的开始,所以如果你的星期在星期日开始,只需减去一周,例如date_trunc('week', current_date)::date - 8将是上一周的星期日

将所有这些放在一起得到:

SELECT count(*), extract(day from createdon) AS period
FROM orders
WHERE servicename =:serviceName 
  AND createdon 
      between date_trunc('week', current_date)::date - 7 
          and date_trunc('week', current_date)::date - 1
GROUP BY extract(day from createdon)
ORDER BY extract(day from createdon);

如果你的列是时间戳列,你可以简单地将createdon转换为日期以摆脱时间部分:

  AND createdon::date 
      between date_trunc('week', current_date)::date - 7 
          and date_trunc('week', current_date)::date

请注意,createdon上的常规索引不会用于该条件,如果需要性能,则需要在createdon::date上创建索引。

如果您不能(或不想)创建这样的索引,则需要使用与between

不同的内容
  AND createdon >= date_trunc('week', current_date)::date - 7 
  AND createdon < date_trunc('week', current_date)::date

(注意使用<而不是<=这是“正在使用的”

另一种选择是将日期信息转换为星期和年份的组合:

AND to_char(createdon, 'iyyy-iw') = to_char(date_trunc('week', current_date)::date - 7, 'iyyy-iw')

请注意,我使用ISO week definition进行了上述操作。如果您使用的是不同的周编号系统,则to_char()功能需要不同的format mask

答案 1 :(得分:0)

如果你使用的是北美周系统(周周从周日开始),那么你的原始方法就足够了,只需使用CAST(<epr> AS <type>)的正确语法:

SELECT   COUNT(*),
         EXTRACT(DAY FROM createdon) period
FROM     orders
WHERE    servicename = 'Cell Tower Monitoring'
AND      createdon BETWEEN CURRENT_DATE - CAST(EXTRACT(DOW FROM CURRENT_DATE) AS INTEGER) - 7 
                       AND CURRENT_DATE - CAST(EXTRACT(DOW FROM CURRENT_DATE) AS INTEGER) - 1
GROUP BY EXTRACT(DAY FROM createdon)
ORDER BY EXTRACT(DAY FROM createdon);

注意:这假定createdonDATE列。如果它是TIMESTAMP(或TIMESTAMP WITH TIME ZONE),则需要略有不同的版本:

SELECT   COUNT(*),
         EXTRACT(DAY FROM createdon) period
FROM     orders
WHERE    servicename = 'Cell Tower Monitoring'
AND      createdon >= CURRENT_TIMESTAMP - INTERVAL '1 day' * (EXTRACT(DOW FROM CURRENT_TIMESTAMP) + 7)
AND      createdon <  CURRENT_TIMESTAMP - INTERVAL '1 day' *  EXTRACT(DOW FROM CURRENT_TIMESTAMP)
GROUP BY EXTRACT(DAY FROM createdon)
ORDER BY EXTRACT(DAY FROM createdon);

如果您想使用ISO周系统(周周从周一开始),那么只需使用ISODOW代替DOW。或者,您可以使用date_trunc('week', ...)功能,例如@a_horse_with_no_name's answer

如果你想使用另一个周系统(f.ex.从星期六开始),你需要在CASE表达式中需要一些额外的逻辑,从而{{1}减去1在那个星期的开始时不会给出预期的结果(星期六f.ex.它将在2周前给出一周)。