簡體   English   中英

從具有創建日期的表中獲取上周的數據

[英]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);

注意 :這假設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的答案

如果你想使用另一個周系統(f.ex.從星期六開始),你需要在CASE表達式中有一些額外的邏輯,因為從DOW減去1將不會在那周的開始時給出預期的結果(星期六f.ex.將在2周前給出一周)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM