#sql #sqlite
#sql #sqlite
Вопрос:
Может ли SQLite проверять установленное покрытие с помощью IN
оператора?
ie (SELECT n from nums where n < 4) IN (1,2,3,4)
(где nums — набор целых чисел) вернул бы true
Я искал документы, но могу найти только документы, в которых используется только одно значение слева от IN
. Тесты показали, что это возможно, но мне нужно подтвердить, что это допустимый вариант использования, а не побочный эффект, подобный способности SQLite возвращать агрегированные запросы без соответствующих GROUP BY
инструкций.
Комментарии:
1. Что именно вы имеете в виду, говоря «это может»? Показанное вами выражение недопустимо ни в одной версии SQLite.
2. НЕТ . Проверяется наличие в наборе только одного значения . То есть:
2 IN (1, 2, 3, 4)
вернул бы true .3. @CL если вы запустите подзапрос, подобный этому, где num — это таблица целых чисел (выберите n из num, где n < 3) В (1,2,3,4), он вернет true. Но если вы запустите (выберите n из num, где n < 4) В (1,2,4), он вернет false, что является ожидаемым поведением. Прошу прощения, я пропустил введенный вопрос.
Ответ №1:
В документации сказано «нет».
Операторы IN и NOT IN принимают одиночный скалярный операнд слева и векторный операнд справа, образованный явным списком из нуля или более скаляров или одним подзапросом.
Акцент мой
Ответ №2:
В документации говорится:
Операторы IN и NOT IN принимают один скалярный операнд слева
Поэтому, если вы используете подзапрос с левой стороны, он обрабатывается как скалярный подзапрос, который ведет себя не так, как вы хотите:
Результатом выражения является значение единственного столбца в первой строке, возвращаемое оператором SELECT. Если ВЫБОР выдает более одной результирующей строки, все строки после первой игнорируются.
Чтобы проверить покрытие набора, вы должны проверить, есть ли в левом наборе какой-либо элемент, которого нет в правом наборе:
WITH a(n) AS (
SELECT n
FROM nums
WHERE n < 4
),
b(n) AS (
VALUES (1), (2), (3), (4)
)
SELECT *
FROM a
WHERE NOT EXISTS (SELECT 1
FROM b
WHERE b.n = a.n);