我在数据库表中有一个 jsonb 字段,其中包含以下数据:
{"access": {
"D2024.06.13": [{"qty": 1, "time": "12:05"}, {"qty": 3, "time": "12:32"}],
"D2024.06.14": [{"qty": 1, "time": "08:37"}]
}}
我想按 10 分钟时段(00:00 至 23:50)按日期和时间对数据进行分组
所以
2024.06.13
12:00 : 1
12:10 : 0
12:20 : 0
12:30 : 3
12:40 : 0
...
{'2024.06.13' : {'12:00':1, '12:10':0, '12:20':0, '12:30':3, '12:40':0 ....}, '2024.06.13' : {'12:00':1 ....}
这样我之后就可以画出时间表了。
分多个步骤:
create table mytable as
( select 1 as x, '{"access": {
"D2024.06.13": [{"qty": 1, "time": "12:05"}, {"qty": 3, "time": "12:32"}],
"D2024.06.14": [{"qty": 1, "time": "08:37"}]
}}'::jsonb as j);
with nrofDays as (
select
min(substr(key,2,10)::date) as fromdate,
max(substr(key,2,10)::date) as todate,
max(substr(key,2,10)::date) - min(substr(key,2,10)::date)+1 as count
from
mytable,
jsonb_each(j->'access')
)
SELECT * FROM nrofDays
自日期 | 今天 | 数 |
---|---|---|
2024-06-13 | 2024-06-14 | 2 |
with nrofDays as (
select
min(substr(key,2,10)::date) as fromdate,
max(substr(key,2,10)::date) as todate,
max(substr(key,2,10)::date) - min(substr(key,2,10)::date)+1 as count
from
mytable,
jsonb_each(j->'access')
)
,timescale as (
select ((select fromdate from nrofDays) + '00:00'::time + interval '1 minute' * t) as tim
from generate_series(0,(24*60*(select count from nrofDays)),10) t
)
select * from timescale
蒂姆 |
---|
2024-06-13 00:00:00.000 |
2024-06-13 00:10:00.000 |
2024-06-13 00:20:00.000 |
2024-06-13 00:30:00.000 |
2024-06-13 00:40:00.000 |
2024-06-13 00:50:00.000 |
2024-06-13 01:00:00.000 |
2024-06-13 01:10:00.000 |
... |
2024-06-14 23:20:00.000 |
2024-06-14 23:30:00.000 |
2024-06-14 23:40:00.000 |
2024-06-14 23:50:00.000 |
2024-06-15 00:00:00.000 |
select
x,
substring(key,2,10)::date as dat,
(value->>'time')::time as tim,
substring(key,2,10)::date + (value->>'time')::time as dt
from
(select x, key, value as v1
from
mytable,
jsonb_each(j->'access')
) x,
jsonb_array_elements(v1)
x | 数据 | 蒂姆 | dt |
---|---|---|---|
1 | 2024-06-13 | 12:05:00 | 2024-06-13 12:05:00.000 |
1 | 2024-06-13 | 12:32:00 | 2024-06-13 12:32:00.000 |
1 | 2024-06-14 | 08:37:00 | 2024-06-14 08:37:00.000 |
with nrofDays as (
select
min(substr(key,2,10)::date) as fromdate,
max(substr(key,2,10)::date) as todate,
max(substr(key,2,10)::date) - min(substr(key,2,10)::date)+1 as count
from
mytable,
jsonb_each(j->'access')
)
,timescale as (
select ((select fromdate from nrofDays) + '00:00'::time + interval '1 minute' * t) as tim
from generate_series(0,(24*60*(select count from nrofDays)),10) t
)
select
timescale.tim,
count(x)
from timescale
left join
(
select
x,
substring(key,2,10)::date as dat,
(value->>'time')::time as tim,
substring(key,2,10)::date + (value->>'time')::time as dt
from
(select x, key, value as v1
from
mytable,
jsonb_each(j->'access')
) x,
jsonb_array_elements(v1)
) d on d.dt between timescale.tim and timescale.tim + interval '1 minute' * 10
group by timescale.tim
order by timescale.tim
MOTE:所选日期始终从“00:00”开始,因此当您希望第一天从“12:05”开始时,您可能需要进行一些调整,但我将其留给您😉
参见:DBFIDDLE