簡體   English   中英

postgresql按年月分組查詢結果

[英]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.

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