Мой агрегатный запрос с 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)
— не уверены, нужно ли вам делать это рекурсивным запросом.