RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.

1. Обзор

select-stmt:

WITH RECURSIVE common-table-expression , SELECT DISTINCT result-column , ALL FROM table-or-subquery join-clause , WHERE expr GROUP BY expr HAVING expr , WINDOW window-name AS window-defn , VALUES ( expr ) , , compound-operator select-core ORDER BY LIMIT expr ordering-term , OFFSET expr , expr

common-table-expression:

compound-operator:

expr:

join-clause:

ordering-term:

result-column:

table-or-subquery:

window-defn:

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

Диаграмма синтаксиса "select-stmt" выше пытается показать как можно больше синтаксиса оператора SELECT в единственной диаграмме, потому что некоторые читатели считают это полезным. Следующее "factored-select-stmt " это альтернативные диаграммы синтаксиса, которые выражают тот же самый синтаксис, но пытаются разделить синтаксис на меньшие куски.

factored-select-stmt:

Обратите внимание на то, что есть пути через диаграммы синтаксиса, которые не позволены на практике. Некоторые примеры:

Эти и другие подобные ограничения синтаксиса описаны в тексте.

SELECT самая сложная команда на языке SQL. Чтобы сделать описание легче, некоторые проходы ниже описывают способ, которым данные, возвращенные оператором SELECT, определяются как серия шагов. Важно иметь в виду, что это чисто иллюстративно: на практике ни SQLite, ни любой другой движок SQL не требуются, чтобы следовать за этим или любым другим определенным процессом.

2. Обработка простого Select

Ядро оператора SELECT это "простой SELECT", показанный на диаграммах select-core и simple-select-stmt ниже На практике большинство операторов SELECT это простые операторы SELECT..

simple-select-stmt:

WITH RECURSIVE common-table-expression , select-core ORDER BY LIMIT expr ordering-term , OFFSET expr , expr

common-table-expression:

expr:

ordering-term:

select-core:

SELECT DISTINCT result-column , ALL FROM table-or-subquery join-clause , WHERE expr GROUP BY expr HAVING expr , WINDOW window-name AS window-defn , VALUES ( expr ) , ,

join-clause:

result-column:

table-or-subquery:

window-defn:

Создание результатов простого оператора SELECT представлено как четыре шага в описании ниже:

  1. Обработка FROM: входные данные для простого SELECT определяются. Входные данные это любая неявно единственная строка с 0 колонками (если нет никакого пункта FROM) или определяется пунктом FROM.

  2. Обработка WHERE: входные данные фильтрованы, используя выражение оператора Where.

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

  4. Обработка ключевых слов DISTINCT/ALL: если запрос "SELECT DISTINCT", дублирующиеся строки удалены из набора строк результата.

Есть два типа простого оператора SELECT: совокупные и неагрегатные запросы. Простой оператор SELECT это агрегатный запрос, если он содержит пункт GROUP BY или одну или несколько агрегатных функций в наборе результатов. Иначе, если простой SELECT не содержит агрегатных функций или пункта GROUP BY, это неагрегатный запрос.

2.1. Определение входных данных (обработка пункта FROM)

Входные данные, используемые простым запросом SELECT, это набор из N по M колонок.

Если FROM опущен от простого оператора SELECT, то входные данные неявно одна строка без колонок (N=1 и M=0).

Если пункт FROM определяется, данные, на которые воздействует простой запрос Select, прибывают из одной или большего количества таблиц или подзапросов (операторы SELECT в круглых скобках), определенных после ключевого слова FROM. Подзапрос, определенный в table-or-subquery после пункта FROM в простом операторе SELECT, обработан, как будто это была таблица, содержащая данные, возвращенные, выполняя подзапрос. У каждой колонки подзапроса есть сортирующая последовательность и близость соответствующего выражения в подзапросе.

Если есть только единственная таблица или подзапрос в пункте FROM, то входные данные, используемые оператором SELECT, являются содержанием названной таблицы. Если есть больше, чем одна таблица или подзапрос в пункте FROM, тогда содержание всех таблиц и/или подзапросов соединяются в единственный набор данных для простого оператора SELECT. Точно то, как данные объединены, зависит от определенного join-operator и join-constraint.

Все объединения в SQLite основаны на декартовом произведении левых и правых наборов данных. Колонки декартова произведения в порядке всех колонок левого набора данных, сопровождаемых всеми колонками правого набора данных. Есть строка в наборе данных декартова произведения, сформированном, объединяя каждую уникальную комбинацию строки от левых и правых наборов данных. Другими словами, если левый набор данных состоит из строк Nleft столбцов Mleft и правого набора данных строк Nright столбцов Mright, то декартово произведение это набор данных Nleft×Nright строк, каждая содержит по Mleft+Mright столбцов.

Если оператор объединения "CROSS JOIN", "INNER JOIN", "JOIN" или запятая (",") и нет никакого пункта ON или USING, то результат соединения просто декартово произведение левых и правых наборов данных. Если у оператора объединения действительно есть пункты ON или USING, те обработаны согласно следующим пунктам маркированного списка:

  • Если есть пункт ON, выражение ON оценено для каждой строки декартова произведения как выражение boolean. Только строки, для которых выражение оценивается к true, включены в набор данных.

  • Если есть пункт USING, каждое из определенных имен столбцов должно существовать в наборах данных слева и справа от оператора объединения. Для каждой пары названных колонок, выражение "lhs.X = rhs.X" оценено для каждой строки декартова произведения как выражение boolean. Только строки, для которых все такие выражения оцениваются как true, включены в набор результатов. Сравнивая значения в результате пункта USING, нормальные правила для обработки сходств, сортирующих последовательностей и значений NULL в сравнениях применяются. Колонка от набора данных на левой стороне оператора объединения считается на левой стороне оператора сравнения (=) в целях предшествования близости и сортирующей последовательности.

    Для каждой пары колонок, определенных пунктом USING, колонка от правого набора данных опущена от набора данных, к которому присоединяются. Это единственная разница между пунктом USING и его эквивалентным ограничением ON.

  • Если ключевое слово NATURAL находится в операторе объединения, неявный пункт USING добавляется к ограничениям соединения. Неявный пункт USING содержит каждое из имен столбцов, которые появляются в левых и в правых входных наборах данных. Если левые и правые входные наборы данных не показывают общих имен столбцов, то ключевое слово NATURAL не имеет никакого эффекта на результаты соединения. USING или пункт ON не могут быть добавлены к соединению, которое определяет ключевое слово NATURAL.

  • Если оператор объединения "LEFT JOIN" или "LEFT OUTER JOIN", после того, как пункты фильтрации ON или USING были применены, дополнительная строка добавляется к выводу для каждой строки в оригинальном левом входном наборе данных, которая не соответствует никакой строке в правом наборе данных. Добавленные строки содержат значения NULL в колонках, которые обычно содержали бы значения, скопированные с правого входного набора данных.

  • Если оператор объединения "RIGHT JOIN" или "RIGHT OUTER JOIN", то после того, как пункты фильтрации ON или USING были применены, дополнительная строка добавляется к выводу для каждой строки в оригинальном правом входном наборе данных, которая не соответствует никакой строке в левом наборе данных. Добавленные строки содержат значения NULL в колонках, которые обычно содержали бы значения, скопированные с левого входного набора данных.

  • "FULL JOIN" или "FULL OUTER JOIN" является комбинацией "LEFT JOIN" и "RIGHT JOIN". Дополнительные строки вывода добавляются для каждой строки в левом наборе данных, которая не соответствует никаким строкам справа, и для каждой строки в правом наборе данных, которая не соответствует никаким строкам слева. Несоответствующие колонки заполнены NULL.

Когда больше, чем две таблицы объединены как часть пункта FROM, операции по соединению обрабатываются слева направо. Другими словами, пункт FROM (A join-op-1 B join-op-2 C) вычисляется как ((A join-op-1 B) join-op-2 C).

2.2. Специальная обработка CROSS JOIN

Нет никакого различия между "INNER JOIN", "JOIN" и ",". Они абсолютно взаимозаменяемы в SQLite. Оператор объединения "CROSS JOIN" приводит к тому же самому результату как "INNER JOIN", "JOIN" и ",", но обработан по-другому оптимизатором запросов, в котором это препятствует тому, чтобы оптимизатор запросов переупорядочил таблицы в соединении. Прикладной программист может использовать оператор CROSS JOIN, чтобы непосредственно влиять на алгоритм, который выбран, чтобы осуществить оператор SELECT. Избегайте использования CROSS JOIN кроме определенных ситуаций, где ручное управление оптимизатором запросов желаемо. Избегайте использования CROSS JOIN рано в разработке применения, поскольку выполнение этого a преждевременная оптимизация. Специальная обработка CROSS JOIN это SQLite-особенность и не является частью стандартного SQL.

2.3. WHERE

Если WHERE определяется, выражение WHERE оценено для каждой строки во входных данных как выражение boolean . Только строки, для которых выражение оператора Where оценивается как true, включены в набор данных перед продолжением. Строки исключены из результата, если оператор Where оценивается как false или NULL.

Для JOIN, INNER JOIN или CROSS JOIN нет никакого различия между ограничительным выражением в операторе Where и в пункте ON. Однако, для LEFT JOIN или LEFT OUTER JOIN различие очень важно. В LEFT JOIN дополнительная строка NULL для правой таблицы добавляется после обработки пункта ON, но перед обработкой оператора Where. Ограничение формы "left.x=right.y" в ON поэтому позволит через добавленные строки NULL правой таблицы. Но если то же самое ограничение будет в операторе Where, то NULL в "right.y" предотвратит выражение "left.x=right.y" = true, и таким образом исключит эту строку из вывода.

2.4. Создание набора строк результата

Как только входные данные из пункта FROM были фильтрованы выражением оператора Where (если таковые имеются), набор строк результата для простого SELECT вычисляется. Точно то, как это сделано, зависит от того, является ли простой SELECT совокупным или неагрегатным запросом, и был ли пункт GROUP BY определен.

Список выражений между SELECT и ключевыми словами FROM известен как список выражений результата. Если выражение результата это специальное выражение "*", всеми колонками во входных данных заменяют то выражение. Если выражение это псевдоним таблицы или подзапроса в пункте FROM, сопровождаемом ".*", всеми колонками от названной таблицы или подзапроса заменяют отдельное выражение. Ошибка использовать "*" или "alias.*" в любом контексте кроме списка выражений результата. Также ошибка использовать "*" или "alias.*" в простом запросе Select, у которого нет пункта FROM.

Количество колонок в строках, возвращенных простым оператором SELECT, равно количеству выражений в списке выражений результата после замены * и alias.*. Каждая строка результата вычисляется, оценивая выражения в списке выражений результата относительно единственной строки входных данных или, для агрегатных запросов, относительно группы строк.

  • Если оператор SELECT неагрегатный запрос, то каждое выражение в списке выражений результата оценено для каждой строки в наборе данных, фильтрованном оператором Where.

  • Если оператор SELECT агрегатный запрос без пункта GROUP BY, то каждое составное выражение в наборе результатов оценено однажды для набора данных. Каждое несоставное выражение в наборе результатов оценено однажды для произвольно отобранной строки набора данных. Та же самая произвольно отобранная строка используется для каждого несоставного выражения. Или, если набор данных содержит нулевые строки, то каждое несоставное выражение оценено против строки полностью из значений NULL.

    Единственная строка данных набора результатов, созданного, оценивая совокупные и несоставные выражения в наборе результатов, формирует результат из агрегатного запроса без пункта GROUP BY. Агрегатный запрос без пункта GROUP BY всегда возвращает точно одну строку данных, даже если есть нулевые строки входных данных.

  • Если оператор SELECT агрегатный запрос с пунктом GROUP BY, то каждое из выражений, определенных как часть пункта GROUP BY, оценено для каждой строки набора данных согласно правилам обработки, указанным ниже для выражений ORDER BY. Каждая строка тогда назначена на "group" на основе результатов, строки, для которых результатами оценки выражений GROUP BY является то же самое, назначены на ту же самую группу. В целях сгруппировать строки, значения NULL считают равными. Обычные правила для отбора сортирующей последовательности , с которой можно сравнить текстовые значения, применяются, оценивая выражения в пункте GROUP BY. Выражения в пункте GROUP BY не должны быть выражениями, которые появляются в результате. Выражения в пункте GROUP BY не могут быть составными выражениями.

    Если пункт HAVING определяется, он оценен однажды для каждой группы строк как выражение boolean. Если результат оценки пункта HAVING false, от группы отказываются. Если пункт HAVING составное выражение, он оценен через все строки в группе. Если пункт HAVING несоставное выражение, он оценен относительно произвольно отобранной строки от группы. Выражение HAVING может относиться к значениям, даже агрегатным функциям, которые не находятся в результате.

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

    Каждая группа входных строк набора данных вносит единственную строку в набор строк результата. Согласно фильтрации связанной с ключевым словом DISTINCT, количество строк, возвращенных агрегатным запросом с пунктом GROUP BY, совпадает с количеством групп строк, произведенных, применяя пункты GROUP BY и HAVING к фильтрованному входному набору данных.

2.5. Голые колонки в агрегатном запросе

Обычный случай это то, что все имена столбцов в агрегатном запросе аргументы агрегатным функциям или иначе появляются в пункте GROUP BY. Столбец результата, который содержит имя столбца, которое не в агрегатной функции и не появляется в пункте GROUP BY (если он существует), назван "голой" колонкой. Пример:

SELECT a, b, sum(c) FROM tab1 GROUP BY a;

В запросе выше колонка "a" это часть пункта GROUP BY и таким образом каждая строка вывода содержит одно из отличных значений для "a". Колонка "c" содержится в агрегатной функции sum(), чтобы произведенная колонка была суммой всех значений "c" в строках, у которых есть то же самое значение для "a". Но каков результат голой колонки "b"? Ответ: результатом "b" будет значение для "b" в одной из входных строк, которые формируют совокупность. Проблема состоит в том, что вы обычно не знаете, которая строка используется, чтобы вычислить "b", и таким образом, во многих случаях значение для "b" не определено.

Специальная обработка происходит, когда агрегатная функция min() или max():

SELECT a, b, max(c) FROM tab1 GROUP BY a;

Если есть точно одна min() или max() в запросе, то все голые колонки в наборе результатов берут значения от входной строки, которая также содержит минимум или максимум. Таким образом в запросе выше значение колонки "b" в выводе будет значением колонки "b" во входной строке, у которой есть самое большое значение "c". Есть ограничения на это специальное поведение min() и max():

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

  2. Если будет две или больше min() или max() в запросе, то голые значения столбцов будут взяты от одной из строк, на которых совокупность имеет их минимальное или максимальное значение. Выбор min() или max() голых значений столбцов произволен. Выбор мог бы отличаться для различных голых колонок в том же самом запросе.

  3. Эта специальная обработка в течение min() или max() работает только на встроенном внедрении тех совокупностей. Если приложение отвергнет встроенные min() или max(), значения, отобранные для голых колонок, будут взяты от произвольной строки.

Большинство других движков базы данных SQL отвергает голые колонки. Если вы будете включать голую колонку в запрос, другие ядра базы данных будут обычно поднимать ошибку. Способность включать голые колонки в запрос является SQLite-определенным расширением. Это считают особенностью, не ошибкой. Посмотрите обсуждение SQLite Forum thread 7481d2a6df8980ff.

2.6. Удаление дублирующихся строк (обработка DISTINCT)

Один из ключевых слов ALL или DISTINCT может следовать за ключевым словом SELECT в простом операторе SELECT. Если простой SELECT это SELECT ALL, то весь набор строк результата возвращен SELECT. Если никакой ALL или DISTINCT не присутствует, то поведение состоит в том, как будто ALL был определен. Если простой SELECT это SELECT DISTINCT, то дублирующиеся строки удалены из набора строк результата, прежде чем это будет возвращено. В целях обнаружить дублирующиеся строки, два значения NULL считаются равными. Обычные правила касаются отбора сортирующей последовательности, чтобы сравнить текстовые значения.

3. Составные Select

Два или больше простых SELECT могут быть связаны вместе, чтобы сформировать составной SELECT, используя оператор UNION, UNION ALL, INTERSECT или EXCEPT, как показано следующей диаграммой:

compound-select-stmt:

WITH RECURSIVE common-table-expression , select-core ORDER BY LIMIT expr UNION UNION ALL select-core INTERSECT EXCEPT ordering-term , OFFSET expr , expr

common-table-expression:

expr:

ordering-term:

select-core:

В составном SELECT всеь учредительные SELECT должны возвратить то же самое количество столбцов результата. Поскольку компоненты составного SELECT должны быть простыми операторами SELECT, они могут не содержать пункты ORDER BY или LIMIT. ORDER BY и LIMIT могут произойти только в конце всего составного SELECT, а затем только если заключительный элемент комплекса не пункт VALUES.

Составной SELECT, созданный, используя оператор UNION ALL, возвращает все строки из SELECT налево от оператора UNION ALL и все строки от SELECT направо от него. Оператор UNION работает как UNION ALL, за исключением того, что дублирующиеся строки удалены из набора конечного результата. Оператор INTERSECT возвращает пересечение результатов левого и правого SELECT. Оператор EXCEPT возвращает подмножество строк, возвращенных левыми SELECT, которые также не возвращены правым SELECT. Дублирующиеся строки удалены из результатов INTERSECT и операторов EXCEPT, прежде чем набор результатов будет возвращен.

В целях определить дублирующиеся строки для результатов составных операторов SELECT значения NULL считают равными другим значениям NULL и отличными от всех ненулевых значений. Сортирующая последовательность, используемая, чтобы сравнить два текстовых значения, определяется, как будто колонки левых и правых операторов SELECT были левыми и правыми операндами оператора равенства (=), за исключением того, что большее предшествование не назначено на сортирующую последовательность, определенную с постфиксным оператором COLLATE. Никакие преобразования близости не применяются ни к каким значениям, сравнивая строки как часть составного SELECT.

Когда три или больше простых SELECT связаны в составной SELECT, они группируются слева направо. Другими словами, если "A", "B" и "C" все являются простыми операторами SELECT, (A op B op C) обработано как ((A op B) op C).

4. ORDER BY

Если у оператора SELECT, который возвращает больше, чем одну строку, нет пункта ORDER BY, порядок, в котором возвращены строки, не определен. Или, если у оператора SELECT действительно есть пункт ORDER BY, то список выражений, приложенных к ORDER BY, определяет порядок, в котором строки возвращены пользователю.

В составном операторе SELECT только у последнего или самого правого простого SELECT может быть пункт ORDER BY. Тот пункт ORDER BY применится через все элементы комплекса. Если самый правый элемент составного SELECT это VALUES, то никакой пункт ORDER BY не позволен.

Строки сначала сортированы на основе результатов оценки крайнего левого выражения в списке ORDER BY, тогда связи нарушены, оценив второе крайнее левое выражение и так далее. Порядок, в котором возвращены две строки, для которых все выражения ORDER BY оценивают, чтобы равняться значениям, не определен. Каждое выражение ORDER BY может произвольно сопровождаться одним из ключевых слов ASC (меньшие значения возвращены сначала) или DESC (большие значения возвращены сначала). Если ни одно, ASC или DESC не определяется, строки сортированы по возрастанию (меньшие значения сначала), это порядок по умолчанию.

SQLite полагает, что значения NULL меньше, чем какие-либо другие значения для целей сортировки. Следовательно, NULL естественно появляются в начале порядка ASC order-by и в конце порядка DESC order-by. Это может быть изменено, используя "ASC NULLS LAST" или "DESC NULLS FIRST".

Каждое выражение ORDER BY обрабатывается следующим образом:

  1. Если ORDER BY постоянное целое число K, выражение считают псевдонимом для K-й колонки набора результатов (колонки пронумерованы слева направо с 1).

  2. Если ORDER BY это идентификатор, который соответствует псевдониму одной из колонок вывода, то выражение считают псевдонимом для той колонки.

  3. Иначе, если выражение ORDER BY это какое-либо другое выражение, оно оценено, и возвращенное значение определеяет порядок вывода строк. Если оператор SELECT это простой SELECT, то ORDER BY может содержать любые произвольные выражения. Однако, если SELECT это составной SELECT, то выражения ORDER BY, которые не являются псевдонимами, чтобы произвести колонки, должны быть точно теми же самыми, как выражение, используемое в качестве колонки вывода.

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

  1. Если выражению ORDER BY назначают сортирующая последовательность, используя постфикс COLLATE, указанная сортирующая последовательность используется.

  2. Иначе, если выражение ORDER BY это псевдоним к выражению, которому назначили сортирующая последовательность, используя постфикс COLLATE, тогда сортирующая последовательность, назначенная на выражение псевдонима, используется.

  3. Иначе, если выражение ORDER BY это колонка или псевдоним выражения, которое является колонкой, тогда сортирующая последовательность по умолчанию для колонки используется.

  4. Иначе сортирующая последовательность BINARY используется.

В составном SELECT все выражения ORDER BY обработаны как псевдонимы для одного из столбцов результата комплекса. Если выражение ORDER BY не псевдоним целого числа, то SQLite ищет крайний левый SELECT в комплексе для столбца результата, который соответствует второму или третьему правилу выше. Если соответствие найдено, поиск остановлен, а выражение обработано как псевдоним для столбца результата, которому это соответствовало. Иначе следующий SELECT направо пробуют и так далее. Если никакое выражение соответствия не может быть найдено в столбцах результата никакого учредительного SELECT, это ошибка. Каждое условие пункта ORDER BY обрабатывается отдельно и может соответствовать столбцам результата от различных операторов SELECT в комплексе.

5. LIMIT

LIMIT используется, чтобы поместить верхнюю границу на количество строк, возвращенных оператором SELECT.

В составном SELECT только последний или самый правый простой SELECT может содержать пункт LIMIT. В составном SELECT LIMIT относится ко всему комплексу, не только к заключительному SELECT. Если самый правый простой SELECT это VALUES, LIMIT не позволен.

Любое скалярное выражение может использоваться в пункте LIMIT, пока это оценивается к целому числу или значению, которое может быть без потерь преобразовано в целое число. Если выражение оценивается к значению NULL или какому-либо другому значению, которое не может быть без потерь преобразовано в целое число, ошибка возвращена. Если выражение LIMIT оценивается к отрицательной величине, то нет никакой верхней границы количества возвращенных строк. Иначе SELECT возвращает только первые N строк своего набора результатов, где N это значение, к которому оценивается выражение LIMIT. Или, если оператор SELECT возвратил бы меньше, чем N строк без пункта LIMIT, то весь набор результатов возвращен.

Выражение, приложенное к дополнительному пункту OFFSET, который может следовать пункту LIMIT, должно также оцениваться к целому числу или значению, которое может быть без потерь преобразовано в целое число. Если у выражения есть пункт OFFSET, то первые M строк набора результатов, возвращенного оператором SELECT, опущены, а возвращены следующие N строк, где M и N это значения, к которым оцениваются пункты OFFSET и LIMIT, соответственно. Или, если SELECT возвратил бы меньше, чем M+N строк, если бы у него не было пункта LIMIT, тогда первые M строк пропускаются, и остающиеся строки (если таковые имеются) возвращены. Если пункт OFFSET оценивается к отрицательной величине, результаты совпадают с тем, если бы он оценился к нолю.

Вместо отдельного пункта OFFSET пункт LIMIT может определить два скалярных выражения, отделенные запятой. В этом случае первое выражение используется в качестве выражения OFFSET, а второе как выражение LIMIT. Это парадоксально, используя пункт OFFSET, вторым из этих двух выражений является OFFSET и первое LIMIT. Перестановка значений сделана намеренно: это максимизирует совместимость с другими системами базы данных SQL. Однако, чтобы избежать беспорядка, программисты сильно поощряются использовать форму пункта LIMIT, который использует ключевое слово "OFFSET" и избегает использования пункта LIMIT с отделенным запятой смещением.

6. VALUES

Фраза "VALUES(expr-list)" означает то же самое, как "SELECT expr-list". Фраза "VALUES(expr-list-1),...,( expr-list-N)" означает то же самое, как "SELECT expr-list-1 UNION ALL ... UNION ALL SELECT expr-list-N". Обе формы то же самое, за исключением того, что количество операторов SELECT в комплексе ограничивается SQLITE_LIMIT_COMPOUND_SELECT, тогда как у количества строк в пункте VALUES нет произвольного предела.

Есть некоторые ограничения на использование пункта VALUES, которые не показывают на диаграммах синтаксиса:

  • VALUES не может сопровождаться ORDER BY.

  • VALUES не может сопровождаться LIMIT.

7. WITH

Операторам SELECT может произвольно предшествовать единственный WITH, который определяет одно или несколько общие выражения таблицы для использования в операторе SELECT.

8. Табличные функции в пункте FROM

Виртуальная таблица, которая содержит скрытые столбцы, может использоваться как a табличная функция в пункте FROM. Аргументы табличной функции становятся ограничениями на столбцах HIDDEN виртуальной таблицы. Дополнительная информация может быть найдена здесь.

9. Отклонения от стандартного SQL

Синтаксис SELECT SQLite отличается немного от стандартного SQL. Эти различия происходят из-за нескольких причин:

  • В середине 2000-х был большой акцент на уменьшение издержек библиотеки, чтобы не использовать слишком много пространства на ограниченных памятью телефонах и подобных им гаджетах.

  • В течение первых лет ведущий разработчик SQLite стремился следовать Postel's Law и быть прощающим и гибким в том, чтобы принимать самый разный ввод.

  • Были ошибки в ранних анализаторах SQLite, который принимает некоторые странные входы.

  • Знание SQL ведущего разработчика было несовершенно.

Безотносительно происхождения входных причуд мы обычно избегаем пытаться "править" их, поскольку любые новые ограничения на входной синтаксис, вероятно, вызвали бы, по крайней мере, несколько миллионов приложений, которые используют SQLite, но развалятся из-за несовместимости. Мы не хотим этого. Цель группы разработчиков SQLite состоит в том, чтобы сохранить совместимость максимально. . Следовательно, если причуда синтаксиса безопасна, мы оставляем ее в покое и документируем ее здесь, вместо того, чтобы попытаться исправить.

9.1. Странные имена JOIN

SQLite принимает весь обычный синтаксис для операторов объединения:

join-operator:

NATURAL LEFT OUTER JOIN , RIGHT FULL INNER CROSS

SQLite на самом деле очень гибок в том, как вы определяете оператор объединения. Общий синтаксис:

blah blah blah JOIN

Где-то между 1 и 3 случаями "blah", каждый из которых может быть любым из "CROSS", "FULL", "INNER", "LEFT", "NATURAL", "OUTER" или "RIGHT". Анализатор SQLite рассматривает каждое из этих ключевых слов как признак соединения, которое может быть объединено в любом порядке. Это создает возможность многих новых и творческих типов соединения вне того, что определяется диаграммой синтаксиса. Некоторые из этих нестандартных типов соединения определенно отвергнуты. Например, вы не можете сказать "INNER OUTER JOIN", потому что это было бы противоречащим. Но можно сказать такие вещи, как "OUTER LEFT NATURAL JOIN", что означает то же самое как "NATURAL LEFT OUTER JOIN". Или можно сказать "LEFT RIGHT JOIN", который совпадает с "FULL JOIN".

Помните: можно использовать эти нестандартные типы соединения, но вы не должны. Придерживайтесь использования стандартного синтаксиса JOIN для совместимости с другими движками базы данных SQL.

9.2. Предшествование соединений запятой и CROSS JOIN

В стандартном SQL соединения, которые используют ключевое слово JOIN, имеют более высокое предшествование, чем соединения запятой. То есть операторы объединения происходят перед операторами запятой. Дело обстоит не так в SQLite, где у всех соединений есть то же самое предшествование.

Рассмотрите этот пример:

... FROM t1, t2 NATURAL FULL JOIN t3 ...

В стандартном SQL FULL JOIN между t2 и t3 произошел бы сначала, и затем к результату левого соединения поперечный присоединяется t1. Но SQLite всегда обращается со всеми соединениями слева направо. Таким образом SQLite сделает перекрестное объединение на t1 и t2 сначала, тогда результат того перекрестного объединения подаст в FULL JOIN с t3. Внутренние объединения неотъемлемо ассоциативны, таким образом, различие очевидно только, если ваш пункт FROM содержит одно или более внешних объединений.

Можно работать вокруг этого и сделать SQL-операторы портативными через все системы, соблюдая следующие стилистические правила:

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

  • Предпочтите LEFT JOIN другим операторам внешнего объединения.

  • Когда в сомнении, используйте круглые скобки, чтобы определить точный порядок соединений.

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