Мой агрегатный запрос с 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.
Как мне это сделать правильно?
Попробуйте добавить HAVING count() > 0, например IFNULL(SELECT json_group_array(SomeColumn) FROM RelationOne HAVING count() > 0, ...).
Не пытайтесь сделать все это в одном запросе. Переместите логику того, когда вызывать второй в RelationTwo, в код, который это выполняет.
@BarrythePlatipus Тестирование длины с использованием json_array_length пришло мне в голову, но мне пришлось бы использовать подзапрос дважды... один раз в тесте и еще раз, чтобы получить результат.
@Dogbert У меня нет GROUP BY в моем подзапросе, поэтому я не могу использовать HAVING.
@Шон Я подумывал сделать все остальное на бэкэнде, но, поскольку большинство запросов используют только RelationOne, в большинстве случаев я бы выполнял ненужный подзапрос и снижал производительность.
Вы выполняете второй только в том случае, если вам нужно...


Добавьте 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
Какую версию sqlite вы используете? Похоже, эта возможность была добавлена в июне 2022 года: sqlite.org/src/info/9322a7c21f1c22ba.
Можешь попробовать group by null having count() > 0?
Обновление SQLite до более новой версии привело к исчезновению ошибки, но пустые массивы по-прежнему приводили к тому, что IFNULL не имел никакого эффекта. Добавление GROUP BY NULL вместе с HAVING, похоже, помогло (как в старых, так и в новых версиях). Спасибо :)
Вы можете попробовать проверить
length(array)— не уверены, нужно ли вам делать это рекурсивным запросом.