如何在postgresql中按周分组和按天区分

zc0qhyus  于 2023-01-17  发布在  PostgreSQL
关注(0)|答案(3)|浏览(166)

样品内容物为:
| 身份证|创建日期|资料|
| - ------|- ------|- ------|
| 1个|2023年1月14日11时52分41秒|{"客户":1、"收支情况:2)|
| 第二章|2023年1月15日11时53分43秒|{"客户":1、"收支情况:2)|
| 三个|2023年1月18日11时51分45秒|{"客户":1、"收支情况:2)|
| 四个|2023年1月15日11时50分48秒|{"客户":1、"收支情况:2)|
ID 4或2应不同。
我希望得到如下结果:
| 年份|星期|客户|付款|
| - ------|- ------|- ------|- ------|
| 二○二三|第二章|第二章|四个|
| 二○二三|三个|1个|第二章|
我用这种方法解决了这个问题

SELECT
    date_part('year', sq.created_dt) AS year,
    date_part('week', sq.created_dt) AS week,
    sum((sq.data->'customers')::int) AS customers,
    sum((sq.data->'payments')::int) AS payments
FROM 
    (SELECT DISTINCT ON (created_dt::date) created_dt, data 
     FROM analytics) sq
GROUP BY 
    year, week
ORDER BY 
    year, week;

然而,这个子查询会使查询变得非常复杂,有没有更好的方法?
我需要按每周对数据进行分组,但我还需要删除重复的日期。

vyswwuz2

vyswwuz21#

生成系列以创建连接表将解决以下问题:

SELECT sum((sq.data->'customers')::int) as customers,
sum((sq.data->'payments')::int) as payments,
date_part('year', dategroup ) as year,
date_part('week', dategroup ) as week,
FROM generate_series(current_date , current_date+interval '1 month' , interval'1 week') AS dategroup
JOIN analytics AS a ON a.created_dt >= dategroup AND a.created_dt <= a.created_dt+interval '1 week'
GROUP BY dategroup
ORDER BY dategroup
0mkxixxg

0mkxixxg2#

首先,我认为你的查询相当简单易懂。
以下是包含with-query的查询,在某些方面它增加了更多可读性:

WITH unique_days_data AS (
  SELECT DISTINCT created_dt::date, data_json
  FROM analytics)
SELECT 
    date_part('year', ud.created_dt) as year,
    date_part('week', ud.created_dt) as week,
    sum((ud.data_json->'customers')::int) as customers,
    sum((ud.data_json->'payments')::int) as payments
FROM unique_days_data ud
GROUP BY year, week
ORDER BY year, week;

区别在于第一个查询使用DISTINCT子句,而不是DISTINCT ON子句。
这是sql fiddle

3z6pesqy

3z6pesqy3#

您可以通过在"* created_id::date *"上添加分区来简化它,然后使用FETCH FIRST n ROWS WITH TIES过滤每周的最后一个聚合记录。

SELECT date_part('year', created_dt) AS year,
       date_part('week', created_dt) AS week,
       SUM((data->>'customers')::int) AS customers,
       SUM((data->>'payments')::int) AS payments
FROM analytics
GROUP BY year, week, created_dt::date
ORDER BY ROW_NUMBER() OVER(
             PARTITION BY date_part('week', created_dt) 
             ORDER     BY created_dt::date DESC
         )
FETCH FIRST 1 ROWS WITH TIES

检查here演示。

相关问题