[英]Group query results by month and year in postgresql
我在 Postgres 服務器上有以下數據庫表:
id date Product Sales
1245 01/04/2013 Toys 1000
1245 01/04/2013 Toys 2000
1231 01/02/2013 Bicycle 50000
456461 01/01/2014 Bananas 4546
我想創建一個查詢,給出Sales
列的SUM
並按月和年對結果進行分組,如下所示:
Apr 2013 3000 Toys
Feb 2013 50000 Bicycle
Jan 2014 4546 Bananas
有沒有一種簡單的方法可以做到這一點?
我不敢相信接受的答案有這么多贊成票——這是一種可怕的方法。
這是使用date_trunc執行此操作的正確方法:
SELECT date_trunc('month', txn_date) AS txn_month, sum(amount) as monthly_sum
FROM yourtable
GROUP BY txn_month
這是不好的做法,但如果您使用,您可能會被原諒
GROUP BY 1
在一個非常簡單的查詢中。
你也可以使用
GROUP BY date_trunc('month', txn_date)
如果您不想選擇日期。
select to_char(date,'Mon') as mon,
extract(year from date) as yyyy,
sum("Sales") as "Sales"
from yourtable
group by 1,2
應 Radu 的要求,我將解釋該查詢:
to_char(date,'Mon') as mon,
:將“日期”屬性轉換為月份縮寫形式的定義格式。
extract(year from date) as yyyy
:Postgresql 的“extract”函數用於從“date”屬性中提取 YYYY 年份。
sum("Sales") as "Sales"
:SUM() 函數將所有“Sales”值相加,並提供區分大小寫的別名,區分大小寫通過使用雙引號保持。
group by 1,2
:GROUP BY 函數必須包含 SELECT 列表中不屬於聚合的所有列(也就是不在 SUM/AVG/MIN/MAX 等函數內的所有列)。 這告訴查詢應該對每個唯一的列組合應用 SUM(),在這種情況下是月和年列。 “1,2”部分是一種簡寫,而不是使用列別名,盡管最好使用完整的“to_char(...)”和“extract(...)”表達式以提高可讀性。
to_char
實際上可以讓你一舉拉出年和月!
select to_char(date('2014-05-10'),'Mon-YY') as year_month; --'May-14'
select to_char(date('2014-05-10'),'YYYY-MM') as year_month; --'2014-05'
或者在上面用戶示例的情況下:
select to_char(date,'YY-Mon') as year_month
sum("Sales") as "Sales"
from some_table
group by 1;
還有另一種方法可以使用 postgres 中的 date_part() 函數來實現結果。
SELECT date_part('month', txn_date) AS txn_month, date_part('year', txn_date) AS txn_year, sum(amount) as monthly_sum
FROM yourtable
GROUP BY date_part('month', txn_date)
謝謝
為什么不只使用date_part
function。https://www.postgresql.org/docs/8.0/functions-datetime.html
SELECT date_part('year', txn_date) AS txn_year,
date_part('month', txn_date) AS txn_month,
sum(amount) as monthly_sum
FROM payment
GROUP BY txn_year, txn_month
order by txn_year;
看一下本教程的示例 6) -> https://www.postgresqltutorial.com/postgresql-group-by/
您需要在 GROUP BY 上調用該函數,而不是調用您在 select 上創建的虛擬屬性的名稱。 我正在按照上述所有答案推薦的方法進行操作,並且收到一column 'year_month' does not exist
錯誤。
對我有用的是:
SELECT
date_trunc('month', created_at), 'MM/YYYY' AS month
FROM
"orders"
GROUP BY
date_trunc('month', created_at)
我在Postgres服務器上有以下數據庫表:
id date Product Sales
1245 01/04/2013 Toys 1000
1245 01/04/2013 Toys 2000
1231 01/02/2013 Bicycle 50000
456461 01/01/2014 Bananas 4546
我想創建一個查詢,該查詢給出“ Sales
列的SUM
,並按月和年對結果進行分組,如下所示:
Apr 2013 3000 Toys
Feb 2013 50000 Bicycle
Jan 2014 4546 Bananas
有沒有簡單的方法可以做到這一點?
Postgres 有幾種類型的時間戳:
不帶時區的時間戳-(最好存儲 UTC 時間戳)您可以在跨國數據庫存儲中找到它。 在這種情況下,客戶端將處理每個國家/地區的時區偏移。
帶時區的時間戳- 時區偏移量已包含在時間戳中。
在某些情況下,您的數據庫不使用時區,但您仍然需要根據本地時區和夏令時對記錄進行分組(例如https://www.timeanddate.com/time/zone/romania/bucharest )
要添加時區,您可以使用此示例並將時區偏移量替換為您的時區偏移量。
"your_date_column" at time zone '+03'
要添加特定於 DST 的 +1 夏令時偏移,您需要檢查您的時間戳是否屬於夏令時。 由於這些間隔隨 1 或 2 天而變化,我將使用不影響月末記錄的近似值,因此在這種情況下,我可以忽略每年的確切間隔。
如果必須構建更精確的查詢,則必須添加條件以創建更多案例。 但粗略地說,當您在數據庫中找到沒有時區的時間戳時,這將適用於按時區和 SummerTime 拆分每月數據:
SELECT
"id", "Product", "Sale",
date_trunc('month',
CASE WHEN
Extract(month from t."date") > 03 AND
Extract(day from t."date") > 26 AND
Extract(hour from t."date") > 3 AND
Extract(month from t."date") < 10 AND
Extract(day from t."date") < 29 AND
Extract(hour from t."date") < 4
THEN
t."date" at time zone '+03' -- Romania TimeZone offset + DST
ELSE
t."date" at time zone '+02' -- Romania TimeZone offset
END) as "date"
FROM
public."Table" AS t
WHERE 1=1
AND t."date" >= '01/07/2015 00:00:00'::TIMESTAMP WITHOUT TIME ZONE
AND t."date" < '01/07/2017 00:00:00'::TIMESTAMP WITHOUT TIME ZONE
GROUP BY date_trunc('month',
CASE WHEN
Extract(month from t."date") > 03 AND
Extract(day from t."date") > 26 AND
Extract(hour from t."date") > 3 AND
Extract(month from t."date") < 10 AND
Extract(day from t."date") < 29 AND
Extract(hour from t."date") < 4
THEN
t."date" at time zone '+03' -- Romania TimeZone offset + DST
ELSE
t."date" at time zone '+02' -- Romania TimeZone offset
END)
我還需要找到按年和月分組的結果。 當我按 TIMESTAMP 對它們進行分組時,總和 function 將它們按日期和分鍾分組,但這不是我想要的。 使用此查詢可能對您有所幫助。
select sum(sum),
concat(year, '-', month, '-', '01')::timestamp
from (select sum(t.final_price) as sum,
extract(year from t.created_at) as year,
extract(month from t.created_at) as month
from transactions t
where status = 'SUCCESS'
group by t.created_at) t
group by year, month;
transactions 表查詢結果正如您在圖片中看到的,在“2022-07-01”中,我在表中有兩列,在查詢結果中它們被組合在一起。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.