Как правильно объединить несколько json_group_array для этого запроса?

Мой агрегатный запрос с group_concat выбирает из одной таблицы, а если результатов нет, он выбирает из другой:

SELECT
    Col1,
    Col2,
    IFNULL(
        SELECT group_concat(SomeColumn) FROM RelationOne,
        SELECT group_concat(SomeColumn) FROM RelationTwo)
FROM MainTable

В результате получается список, разделенный запятыми, из RelationOne или RelationTwo. Вместо этого я хочу использовать json_group_array:

SELECT
    Col1,
    Col2,
    IFNULL(
        SELECT json_group_array(SomeColumn) FROM RelationOne,
        SELECT json_group_array(SomeColumn) FROM RelationTwo)
FROM MainTable

При этом создается массив JSON со значениями из RelationOne, но если RelationOne нет данных, он создает пустой массив [] вместо NULL, поэтому, если есть какие-либо значения из RelationTwo, они никогда не будут показаны, потому что [] != NULL.

Как мне это сделать правильно?

Вы можете попробовать проверить length(array) — не уверены, нужно ли вам делать это рекурсивным запросом.

Barry the Platipus 16.07.2024 13:24

Попробуйте добавить HAVING count() > 0, например IFNULL(SELECT json_group_array(SomeColumn) FROM RelationOne HAVING count() > 0, ...).

Dogbert 16.07.2024 13:30

Не пытайтесь сделать все это в одном запросе. Переместите логику того, когда вызывать второй в RelationTwo, в код, который это выполняет.

Shawn 16.07.2024 15:49

@BarrythePlatipus Тестирование длины с использованием json_array_length пришло мне в голову, но мне пришлось бы использовать подзапрос дважды... один раз в тесте и еще раз, чтобы получить результат.

TheHvidsten 16.07.2024 21:26

@Dogbert У меня нет GROUP BY в моем подзапросе, поэтому я не могу использовать HAVING.

TheHvidsten 16.07.2024 21:27

@Шон Я подумывал сделать все остальное на бэкэнде, но, поскольку большинство запросов используют только RelationOne, в большинстве случаев я бы выполнял ненужный подзапрос и снижал производительность.

TheHvidsten 16.07.2024 21:28

Вы выполняете второй только в том случае, если вам нужно...

Shawn 16.07.2024 21:30
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
7
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Добавьте having count() > 0 в свой подзапрос, чтобы он не возвращал строк, если нет значений. (Да, работаю без группы.)

Вот пример:

with numbers(x) as (values (1), (2), (3))
select
  ifnull(
    (select json_group_array(x) from numbers b where b.x < a.x),
    'None'
  )
from numbers a;

Выход:

[]
[1]
[1,2]

Теперь добавляю having count() > 0:

with numbers(x) as (values (1), (2), (3))
select
  ifnull(
    (select json_group_array(x) from numbers b where b.x < a.x having count() > 0),
    'None'
  )
from numbers a;

Новый результат:

None
[1]
[1,2]

Когда я добавляю HAVING count() > 0 в свой подзапрос, я получаю сообщение об ошибке a GROUP BY clause is required before HAVING

TheHvidsten 16.07.2024 23:14

Какую версию sqlite вы используете? Похоже, эта возможность была добавлена ​​в июне 2022 года: sqlite.org/src/info/9322a7c21f1c22ba.

Dogbert 16.07.2024 23:22

Можешь попробовать group by null having count() > 0?

Dogbert 16.07.2024 23:24

Обновление SQLite до более новой версии привело к исчезновению ошибки, но пустые массивы по-прежнему приводили к тому, что IFNULL не имел никакого эффекта. Добавление GROUP BY NULL вместе с HAVING, похоже, помогло (как в старых, так и в новых версиях). Спасибо :)

TheHvidsten 17.07.2024 13:55

Другие вопросы по теме