Агрегировать SQLite-запрос по нескольким таблицам, используя JSON1 - PullRequest
0 голосов
/ 02 мая 2020

Я не могу разобраться со следующей проблемой. На днях я узнал, как использовать семейство функций JSON1, но на этот раз это похоже на проблему SQL.

Это моя настройка базы данных:

CREATE TABLE persons(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE)
CREATE TABLE interests(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE)
CREATE TABLE persons_interests(person INTEGER, interest INTEGER, FOREIGN KEY(person) REFERENCES persons(id), FOREIGN KEY(interest) REFERENCES interests(id))

INSERT INTO persons(name) VALUES('John')
INSERT INTO persons(name) VALUES('Jane')

INSERT INTO interests(name) VALUES('Cooking')
INSERT INTO interests(name) VALUES('Gardening')
INSERT INTO interests(name) VALUES('Relaxing')

INSERT INTO persons_interests VALUES(1, 1)
INSERT INTO persons_interests VALUES(1, 2)
INSERT INTO persons_interests VALUES(2, 3)

Основываясь на этих данных, я хотел бы получить следующий вывод, который представляет все интересы всех людей, сгруппированных в один массив JSON:

[{name: John, interests:[{name: Cooking},{name: Gardening}]}, {name: Jane, interests:[{name: Relaxing}]}]

Теперь я попытался сделать следующее. Излишне говорить, что это не дает мне то, что я хочу:

SELECT p.name, json_object('interests', json_group_array(json_object('name', i.name))) interests
FROM persons p, interests i
JOIN persons_interests pi ON pi.person = p.id AND pi.interest = i.id

Нежелательный вывод:

John|{"interests":[{"name":"Cooking"},{"name":"Gardening"},{"name":"Relaxing"}]}

Любая помощь высоко ценится!

1 Ответ

0 голосов
/ 02 мая 2020

Для использования json_group_array вы должны сгруппировать строку, в вашем случае по человеку, за исключением того, что вам нужна только одна строка со всеми вашими результатами.

Пример 1)

Эта первая версия даст вам 1 json объект на человека, так что результатом будет N строк для N человек:

SELECT json_object( 'name ',
                    p.name, 
                    'interests', 
                    json_group_array(json_object('name', i.name))) jsobjects
FROM persons p, interests i
JOIN persons_interests pi ON pi.person = p.id AND pi.interest = i.id
group by p.id ;

Пример 2)

Эта вторая версия выдаст 1 большой массив json, содержащий всех людей, но вы получите только одну строку.

SELECT json_group_array(jsobjects) 
FROM (

    SELECT json_object( 'name ',
                        p.name, 
                        'interests', 
                        json_group_array(json_object('name', i.name))) jsobjects
    FROM persons p, interests i
    JOIN persons_interests pi ON pi.person = p.id AND pi.interest = i.id
    group by p.id 
) jo ;
...