使用以下查询检索上周数据,但我收到错误
Postgres ERROR:语法错误在或接近" CAST"位置:127
我不知道错误的位置:
ImageMagic
答案 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);
注意:这假定createdon
是DATE
列。如果它是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周前给出一周)。