【发布时间】:2019-08-20 14:42:41
【问题描述】:
create table store (id integer primary key, name text);
create table opening (store integer references store(id),
wday text, start integer, end integer);
insert into store (name) values ('foo'), ('bar');
insert into opening (store, wday, start, end)
values (1, 'mon', 0, 60),
(1, 'mon', 60, 120),
(1, 'tue', 180, 240),
(1, 'tue', 300, 360),
(2, 'wed', 0, 60),
(2, 'wed', 60, 120),
(2, 'thu', 180, 240);
我正在尝试以 JSON 格式在一个查询中查询所有商店及其各自的营业时间。
{
"1": {
"name": "foo",
"openings": {
"mon": [ [ 0, 60 ], [ 60, 120 ] ],
"tue": [ [180, 240 ], [ 300, 360 ] ]
}
},
"2": {
"name": "bar",
"openings": {
"wed": [ [0,60], [60,120] ],
"thu": [ [180,240] ]
}
}
}
这是我尝试过的演变过程。我想我想念一种方法来做多级json_group_object。
select * from opening;
store wday start end
---------- ---------- ---------- ----------
1 mon 0 60
1 mon 60 120
1 tue 180 240
1 tue 300 360
2 wed 0 60
2 wed 60 120
2 thu 180 240
select * from opening group by store;
store wday start end
---------- ---------- ---------- ----------
1 mon 0 60
2 wed 0 60
select json_group_object(store, wday) from opening group by store;
json_group_object(store, wday)
-----------------------------------------
{"1":"mon","1":"mon","1":"tue","1":"tue"}
{"2":"wed","2":"wed","2":"thu"}
select store, wday, json_group_array(json_array(start, end))
from opening group by store, wday;
store wday json_group_array(json_array(start, end))
---------- ---------- ----------------------------------------
1 mon [[0,60],[60,120]]
1 tue [[180,240],[300,360]]
2 thu [[180,240]]
2 wed [[0,60],[60,120]]
select json_object('id', store,
'openings', json_group_object(wday, json_group_array(json_array(start, end)))
) from opening group by store, wday;
Error: near line 17: misuse of aggregate function json_group_array()
select json_object('id', store,
'openings', json_object(wday, json_group_array(json_array(start, end)))
) from opening group by store, wday;
{"id":1,"openings":{"mon":[[0,60],[60,120]]}}
{"id":1,"openings":{"tue":[[180,240],[300,360]]}}
{"id":2,"openings":{"thu":[[180,240]]}}
{"id":2,"openings":{"wed":[[0,60],[60,120]]}}
我如何在这里按相同的 id 分组?
将为与group by 对应的每个唯一值返回一行。因此,最外面的select 必须有一个group by store。
select json_group_object(store, x)
from (
select
store,
json_object(
'id', store,
'openings', json_object(wday, json_group_array(json_array(start, end)))
) x
from opening group by store, wday
) group by store;
然而,这个内部查询返回文字 JSON。将内部 JSON 解码然后在最外层的查询中全部编码似乎很愚蠢。
{"1":"{\"id\":1,\"openings\":{\"mon\":[[0,60],[60,120]]}}","1":"{\"id\":1,\"openings\":{\"tue\":[[180,240],[300,360]]}}"}
{"2":"{\"id\":2,\"openings\":{\"thu\":[[180,240]]}}","2":"{\"id\":2,\"openings\":{\"wed\":[[0,60],[60,120]]}}"}
Postgres 中的 IIRC 这个返回 JSON 的内部查询不会返回文字 JSON,但无论哪种方式,我都对如何继续感到困惑。
感谢您的帮助。
【问题讨论】:
-
尝试在最后一次选择的外部使用
json(x)。 -
谢谢肖恩。这确实有效,但这是否将每个内部查询行编码为 JSON,然后使用
json(x)在外部解码,然后将整个结果集重新编码为一个整体?听起来效率低下。想知道解释计划是否显示了这一点。编辑 - 是的,但我不确定我是否 100% 遵循它 -
是的,确实如此。在函数调用中使用辅助数据来避免一直这样做的技巧无法跨越子查询边界 iirc。
-
好吧,我就是这么想的。好的,除非我缺少另一种明显的方式,否则我可能会选择生成不同的 JSON 形状。
标签: json sqlite sqlite-json1