首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何根据JSON日期范围减去两个JSON INT?

如何根据JSON日期范围减去两个JSON INT?
EN

Stack Overflow用户
提问于 2022-08-03 21:07:15
回答 2查看 70关注 0票数 0

我有一个包含userName和entry_data (包含值和entryDate的JSON用户输入)的数据库。

下面是表的一个示例:

代码语言:javascript
复制
| userName | value | entryDate |
| ________ | _____ | __________|
| Aaron    | 1234  | 7/25/2022 |
| Aaron    | 6463  | 7/26/2022 |
| Aaron    | 8375  | 7/27/2022 |
| Aaron    | 2734  | 7/28/2022 |
| Aaron    | 4563  | 7/29/2022 |
| Aaron    | 7374  | 7/30/2022 |
| Aaron    | 8923  | 7/31/2022 |
| Aaron    | 6737  | 8/1/2022  |
| Aaron    | 1374  | 8/2/2022  |
| Aaron    | 1834  | 8/3/2022  |
| Aaron    | 3646  | 8/4/2022  |
| Aaron    | 7834  | 8/5/2022  |
| Aaron    | 2473  | 8/6/2022  |
| Aaron    | 4673  | 8/7/2022  |

我的任务是求和值(totalValue),按周(7/25-7/31 = week1Value,8/1-8/7 = week2Value)求和值,并逐周查找不同的值(week2Value - week1Value = WoWDifference),因此如下所示:

代码语言:javascript
复制
| userName | totalValue | week1Value | week2Value | WoWDifference |
| ________ | __________ | __________ | __________ | _____________ |
| Aaron    |   76,071   |   39,666   |   36,405   |    -3,261     | 

我不熟悉“分组”和减去日期范围内的值。到目前为止,我是这样对事物进行分组的:

代码语言:javascript
复制
SELECT
    userName,
    cast((entry_data ->> 'value') as Int) as totalValue,
    case
         when (entry_data ->> 'week1Value')::DATE BETWEEN '2022-07-25' AND '2022-07-31' then 'week1'
         when (entry_data ->> 'week2Value')::DATE BETWEEN '2022-08-01' AND '2022-08-07' then 'week2'
    end as timeframe,
FROM entry

输出:

代码语言:javascript
复制
| userName | totalValue | timeframe|
| ________ | __________ | ________ |
| Aaron    |   39,666   |  week1   |
| Aaron    |   36,405   |  week2   |

如何按周提取totalValue之和,以得到周之间的差额?

EN

回答 2

Stack Overflow用户

发布于 2022-08-03 23:12:36

试试这个:

代码语言:javascript
复制
SELECT
    userName,
    sum(entry_data ->> 'value') as totalValue,
    case when (entry_data ->> 'week1Value')::DATE BETWEEN '2022-07-25' AND '2022-07-31' 
             then sum(entry_data ->> 'value') AS week1 /* changed */
    case when (entry_data ->> 'week2Value')::DATE BETWEEN '2022-08-01' AND '2022-08-07' 
             then sum(entry_data ->> 'value') AS week2 /* changed */
FROM entry
group by userName /* changed */
票数 0
EN

Stack Overflow用户

发布于 2022-08-05 00:02:34

另一种方法(类似于@Y )假设日期是连续的。

代码语言:javascript
复制
with data as
  (select *, ceil(row_number() over (order by 0)::decimal/7)::integer rn 
  from entry)
select username,sum(to_number(entry_data->>'value','9999999')) total_value,
  sum (case when rn = 1 then
  to_number(entry_data->>'value','9999999')
  else 0
end) week_1_total,
sum (case when rn = 2 then
  to_number(entry_data->>'value','9999999')
  else 0
end) week_2_total
from data
group by username;

或者,使用CROSSTAB使用下面的查询-

代码语言:javascript
复制
SELECT *
FROM   crosstab(
   'SELECT username, total_value,
    week_no, total_weekly
    FROM  (
        with data as (
            select e.username, e.rn week_no,
            (select sum(to_number(entry_data->>$$value$$,$$9999999$$)) 
            from entry) total_value,
            sum(to_number(entry_data->>$$value$$,$$9999999$$)) total_weekly
            from 
            (select *, 
            ceil(row_number() over 
            (partition by username order by 0)::decimal/7)::integer rn 
            from entry) e
            group by
            e.username, total_value, e.rn
            )
        select username,
        week_no,
        total_value,
        total_weekly
        from data
        union all
        select username,
        (select max(week_no) from data) + 
        row_number() over (partition by username order by 0),
        total_value,
        total_weekly - coalesce(lag(total_weekly) over (order by week_no), 0)
        from data ) x 
        ORDER  BY 1' 
        ,$$VALUES (1), (2), (3), (4), (5), (6)$$
   ) AS ct 
   ("username" text, 
   "total_value" int,
   "Week_1" int, 
   "Week_2" int, 
   "Week_3" int,
   "Weekdiff_1" int, 
   "Weekdiff_2" int, 
   "Weekdiff_3" int
);

请参阅小提琴这里

上面的小提琴还探索了案例外推数据使用crosstab和手动方法的枢轴。

仍然有一些以上可能无法处理的情况,例如如果有少于7行或它没有整整一周,但它提供了一种通用的方法,可以修改以满足特定的用例。

values clause of crosstab中的硬编码也可以用一个查询来代替,以生成一个值的两倍的数字列表,因为给定的用户名有几周的时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73227825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档