Как получить вложенные данные JSON из SQLite с помощью многоуровневой группы? - PullRequest
1 голос
/ 29 марта 2019
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]]}}

Как здесь сгруппировать по одному и тому же идентификатору?

Будет возвращена строка для каждого уникального значения, соответствующего 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]]}}"}

IIRC в Postgres этот внутренний запрос, который возвращает JSON, не вернет литеральный JSON, но в любом случае я 'Я растерялся, как продолжить.

Спасибо за любую помощь.

...