[英]Get last week's data from a table with a creation date
使用以下查詢檢索上周數據,但我收到錯誤
Postgres ERROR:語法錯誤在“CAST”或附近位置:127
我不知道錯誤在哪里:
SELECT count(*), extract(day from createdon) AS period
FROM orders
WHERE servicename =:serviceName AND createdon BETWEEN
CAST(NOW() AS CAST(DATE-EXTRACT(DOW FROM NOW()) AS INTEGER-7)) AND
CAST(NOW() AS CAST(DATE-EXTRACT(DOW from NOW()) AS INTEGER))
GROUP BY extract(day from createdon)
ORDER BY extract(day from createdon);
你太復雜了。 要獲得上周的數據,只需在“本周開始”減去7天后獲取所有內容:
可以使用date_trunc('week', current_date)
來評估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周定義 。 如果您使用的是不同的周編號系統,則需要為to_char()
函數使用不同的格式掩碼 。
如果您使用的是北美周系統(周周從周日開始),那么您的原始方法就足夠了,只需使用正確的CAST(<epr> AS <type>)
語法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的答案 。
如果你想使用另一個周系統(f.ex.從星期六開始),你需要在CASE
表達式中有一些額外的邏輯,因為從DOW
減去1
將不會在那周的開始時給出預期的結果(星期六f.ex.將在2周前給出一周)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.