Запрос Room/SQLite с min(...) без возврата результата, если ничего не найдено

В настоящее время застрял на контрольно-пропускном пункте SQL, и мне не удается найти какие-либо ответы на мою проблему из-за того, насколько общими являются соответствующие слова.

У меня есть два запроса, которые кажутся одинаковыми, но дают разные результаты.

Для этих примеров предположим, что записи с id 123 НЕТ, а MyTable имеет следующие столбцы: id, time и data.

Один запрос для записи, которая не существует со всеми столбцами

SELECT id, data, time FROM MyTable WHERE id = 123

который не возвращает никаких результатов.

Другой запрос также относится к записи, которая не существует со всеми столбцами.

SELECT id, data, min(time) FROM MyTable WHERE id = 123

который возвращает один результат, где каждый столбец имеет значение null

Пример этого сценария из Android Studio:

не возвращает никаких результатов, как хотелось бы

возвращает один результат со всеми столбцами как null

такая же проблема возникает, даже если я называю столбец с тем же именем

Я пытаюсь добиться того же поведения во втором запросе, что и в первом; если результатов нет, то не возвращайте никаких результатов вместо того, чтобы возвращать один результат со всеми столбцами с нулевыми значениями.

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

Это невозможно или есть способ добиться этого в Android Room Library/SQLite?

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

Чтобы вернуть что-либо, кроме одного значения, функция, связанная с запросом, должна вернуть объект. Результаты могут зависеть от возвращаемых объектов. Поэтому вам следует отредактировать свой вопрос, включив в него функции, связанные с запросами и соответствующими возвращаемыми объектами.

MikeT 28.04.2023 04:32

Что вы подразумеваете под: ... возвращает один результат, где каждый столбец имеет значение null? Если id=123 отсутствует, то оба запроса не возвращают никаких результатов.

forpas 28.04.2023 07:50

Я предполагаю, что OP запрашивает с другим контекстом, чем запрос обычной таблицы, но функция с табличным значением, которая, вероятно, каким-то образом приводит к строке нулей... самый простой способ обойти это - добавить нулевую проверку в предложение where, чтобы отфильтровать нарушение ряд, напр. coalesce(id,time,data) is not null но это основано только на предположении... было бы полезно, если бы OP прояснил вопрос

DarkSquirrel42 28.04.2023 11:41

@forpas Я имею в виду, что когда я запрашиваю указанные столбцы, результат возвращает объект со всеми полями, для которых установлено значение null, но если я использую *, он не возвращает результатов

Shadow 28.04.2023 18:44

@DarkSquirrel42 Не знаю, как я могу пояснить, но я по крайней мере включу несколько примеров из моего варианта использования и скриншоты.

Shadow 28.04.2023 18:45

... результат возвращает объект со всеми полями, для которых установлено значение null, это невозможно, если нет id=123. Можете ли вы воспроизвести это с примерами данных в скрипке ?

forpas 28.04.2023 18:48

@forpas Я полагаю, что на самом деле могу неправильно понять запрос, проблема возникает только в том случае, если в запрос включен минимум (столбец), например: SELECT id, min(time) FROM MyTable WHERE id = 123. Я обновлю вопрос, чтобы отразить это правильно.

Shadow 28.04.2023 18:51

Я обновил вопрос, указав фактический случай, приношу извинения за неправильное толкование фактической причины, я не осознавал, что это ограничивается использованием min(...).

Shadow 28.04.2023 18:55

@forpas Боюсь, я не знаю, как использовать этот веб-сайт, чтобы привести скрипку в качестве примера моей ситуации.

Shadow 28.04.2023 18:57
0
9
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Этот:

SELECT id, data, min(time) FROM MyTable WHERE id = 123

является агрегированным запросом без предложения GROUP BY, и поэтому он всегда возвращает ровно 1 строку.

Если вы хотите, чтобы он ничего не возвращал в случае невыполнения условия в предложении WHERE, используйте EXCEPT:

SELECT id, data, min(time) FROM MyTable WHERE id = 123
EXCEPT
SELECT null, null, null; -- as many null columns as the main selection 

или используйте нестандартную функцию SQL SQL с предложением HAVING в агрегированном запросе без предложения GROUP BY (что не будет работать в других базах данных):

SELECT id, data, min(time) FROM MyTable WHERE id = 123
HAVING id IS NOT NULL;

или, с оговоркой GROUP BY:

SELECT id, data, min(time) FROM MyTable WHERE id = 123
GROUP BY id
HAVING id IS NOT NULL;

Смотрите демо.

Это сработало отлично, и я могу жить с этим компромиссом. Если у кого-то еще нет лучшего способа сделать это, учитывая комментарии к моему вопросу, то это ответ, который я выбрал для своей проблемы. Также сегодня я узнал кое-что новое, так что спасибо за объяснение, почему это происходит.

Shadow 28.04.2023 19:06

@Shadow проверьте альтернативное решение в моем отредактированном ответе, который, как я уже упоминал, нестандартен и работает только в SQLite.

forpas 28.04.2023 19:25

к сожалению, HAVING не принимается в запросе Android Studio и библиотеке комнат, так что для меня это не вариант. Было бы здорово просто использовать этот единственный столбец вместо того, чтобы записывать их все в except select ....

Shadow 28.04.2023 19:27

так что кажется, что HAVING можно использовать, но он ДОЛЖЕН сопровождаться GROUP BY... в соответствии с их документацией developer.android.com/reference/android/arch/persistence/db/‌​…

Shadow 28.04.2023 19:37

@Shadow, вы можете добавить предложение GROUP BY, не затрагивая функциональность этого запроса: SELECT id, data, min(time) FROM MyTable WHERE id = 123 GROUP BY id HAVING id IS NOT NULL;: dbfiddle.uk/xwzRUphx

forpas 28.04.2023 19:42

Готово, идеально! Можете ли вы обновить свой ответ этим? Я уверен, что другие, ищущие это, сочтут это наиболее полезным.

Shadow 28.04.2023 19:43

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