Почему агрегатные функции не разрешены в предложении where
Я ищу разъяснения по этому вопросу. Я пишу два запроса ниже:
У нас есть таблица имени сотрудника с колонками ID, имя, зарплата
Query 1 не работает, но Query 2 работает. Исходя из моего опыта разработки, я чувствую возможное объяснение этому:
Sum () работает с набором значений, указанных в аргументе. Здесь передается столбец salary, поэтому он должен складывать все значения этого столбца. Но внутри предложения where записи проверяются одна за другой, как первая запись 1 проверяется для теста и так далее. Таким образом, сумма (зарплата) не будет вычислена, так как ей нужен доступ ко всем значениям столбца, и только тогда она вернет значение.
Запрос 2 работает так, как substring_index () работает с одним значением, и, следовательно, здесь он работает с предоставленным ему значением.
Можете ли вы подтвердить мое понимание.
4 ответа
С другой стороны, агрегация выполняется только после того, как все строки (которые проверяют все предикаты) были прочитаны.
Почему мы можем использовать агрегатную функцию в предложении where
Агрегатные функции работают с наборами данных. Предложение WHERE не имеет доступа ко всему набору, а только к строке, над которой он в данный момент работает.
Конечно, вы можете использовать предложение HAVING:
Использование «работает», так как запрос идет прямо к строкам в этом столбце, в то время как там, где происходит сбой, поскольку запрос продолжает циклически повторяться, когда условия не выполняются.
Использование групповых функций
В SQL имеется множество предопределенных агрегатных функций, которые можно использовать для написания запросов для получения именно такой информации. Предложение GROUP BY указывает, как группировать строки из таблицы данных при агрегировании информации, тогда как предложение HAVING отфильтровывает строки, которые не принадлежат указанные группы.
Агрегатные функции выполняют различные действия, такие как подсчет всех строк в таблице, усреднение данных столбца и суммирование числовых данных. Агрегаты также могут искать в таблице, чтобы найти самые высокие значения «MAX» или самые низкие значения «MIN» в столбце. Как и в случае других типов запросов, вы можете ограничить или отфильтровать строки, с которыми работают эти функции, с помощью предложения WHERE. Например, если менеджеру необходимо знать, сколько сотрудников работает в организации, для получения этой информации можно использовать агрегатную функцию COUNT (*). Функция COUNT (*), показанная в приведенном ниже операторе SELECT, подсчитывает все строки в Таблица.
Таблица результатов для функции COUNT (*) представляет собой один столбец из одной строки, известный как скалярный результат или значение. Обратите внимание, что таблица результатов имеет заголовок столбца, который соответствует имени агрегатной функции, указанной в предложении SELECT.
Некоторые из часто используемых агрегатных функций приведены ниже:
Ключевые слова ALL и DISTINCT являются необязательными и выполняются так же, как и с предложениями SELECT, которые вы научились писать. Ключевое слово ALL является значением по умолчанию, где эта опция разрешена. Выражение, указанное в синтаксисе, может быть константой, функцией, или любая комбинация имен столбцов, констант и функций, связанных арифметическими операторами. Однако агрегатные функции чаще всего используются с именем столбца. За исключением функции COUNT, все агрегатные функции не учитывают значения NULL.
Есть два правила, которые вы должны понимать и соблюдать при использовании агрегатов:
Агрегатные функции могут использоваться как в предложениях SELECT, так и в предложениях HAVING (предложение HAVING будет описано далее в этой главе).
Агрегатные функции нельзя использовать в предложении WHERE. Его нарушение приведет к тому, что групповая функция Oracle ORA-00934 не допускает здесь сообщения об ошибке.
Агрегатные функции могут использоваться как в предложениях SELECT, так и в предложениях HAVING (предложение HAVING будет описано далее в этой главе).
Агрегатные функции нельзя использовать в предложении WHERE. Его нарушение приведет к тому, что групповая функция Oracle ORA-00934 не допускает здесь сообщения об ошибке.
иллюстрации
Приведенный ниже запрос SELECT подсчитывает количество сотрудников в организации.
Приведенный ниже запрос SELECT возвращает среднюю зарплату сотрудников в организации.
Приведенный ниже запрос SELECT возвращает сумму зарплат сотрудников в организации.
Приведенный ниже запрос SELECT возвращает самые старые и самые последние даты приема сотрудников в организации.
ГРУППА ПО
Агрегатные функции обычно используются вместе с предложением GROUP BY. Предложение GROUP BY позволяет использовать агрегатные функции для ответа на более сложные вопросы управления, такие как:
Alex tools
Агрегатные функции в PostgreSQL
Как и большинство других реляционных баз данных, PostgreSQL поддерживает агрегатные функции. Агрегатная функция вычисляет один результат из нескольких входных строк. Например, есть агрегаты для вычисления количества (count), суммы (sum), среднего (avg), максимального (max) и минимального (min) количества строк.
В качестве примера, мы можем найти самую старшую персону с помощью запроса:
Если бы мы хотели узнать, из какой записи (или записей) произошло это чтение, мы могли бы попробовать:
но это не будет работать, так как агрегатный max не может быть использован в предложении WHERE. (Это ограничение существует, потому что предложение WHERE определяет, какие строки будут включены в агрегатный расчет; поэтому, очевидно, его необходимо оценить до вычисления агрегатных функций). Однако, как это часто бывает, запрос может быть перезаписан для достижения желаемого результата с помощью подзапроса:
Это нормально, потому что подзапрос является независимым вычислением, которое вычисляет свой собственный агрегат отдельно от того, что происходит во внешнем запросе.
Агрегаты также очень полезны в сочетании с предложениями GROUP BY. Например, мы можем получить максимальный возраст, соотвествующий каждому имени с помощью:
что дает нам по одной строке на каждое имя. Каждый совокупный результат вычисляется по строкам таблицы, соответствующим этому имени. Мы можем отфильтровать эти сгруппированные строки, используя HAVING:
что дает нам те же результаты только для имен, у которых все значения age ниже 40. Наконец, если мы заботимся только об именах, названия которых начинаются с «П», мы могли бы сделать:
Важно понимать взаимодействие между агрегатами и предложениями WHERE и HAVING в SQL. Принципиальное различие между WHERE и HAVING заключается в следующем: WHERE выбирает входные строки до вычисления групп и агрегатов (таким образом, он контролирует, какие строки входят в вычисления агрегатов), тогда как HAVING выбирает строки групп после вычисления групп и агрегатов. Таким образом, предложение WHERE не должно содержать агрегатных функций; нет смысла пытаться использовать агрегат, чтобы определить, какие строки будут входными для агрегатов. С другой стороны, предложение HAVING всегда содержит агрегатные функции. (Строго говоря, вам разрешено написать предложение HAVING, в котором не используются агрегаты, но это редко имеет пользу. Такое же условие можно было бы использовать более эффективно на этапе WHERE.)
В предыдущем примере мы можем применить ограничение по имени в WHERE, так как оно не требует агрегирования. Это более эффективно, чем добавление ограничения к HAVING, потому что мы избегаем выполнения группирования и агрегирования вычислений для всех строк, которые не проходят проверку WHERE.
Оператор SELECT
Наиболее используемым, но и самым сложным оператором является оператор выборки SELECT. Он позволяет производить выборку данных из таблиц и преобразовывать к нужному виду полученные результаты.
Результатом выполнения оператора SELECT является таблица. К этой таблице может быть снова применен оператор SELECT и т.д., то есть такие операторы могут быть вложены друг в друга. Вложенные операторы SELECT называют подзапросами.
Синтаксис оператора SELECT использует следующие основные предложения:
Кратко пояснить смысл предложений оператора SELECT можно следующим образом:
База данных для примеров
Дальше будет много примеров и логично постоянно использовать одну и ту же БД, что бы не рисовать каждый раз новые. На основании базы данных ниже будут продемонстрированы все примеры, не только в этой статье, но и в других.
Постановка задачи: пусть требуется разработать БД для предметной области «Поставка деталей»!
Требуется хранить следующую информацию:
Значения таблицы P:
| pnum | pname |
|---|---|
| 1 | Иванов |
| 2 | Петров |
| 3 | Сидоров |
| 4 | Кузнецов |
Значения таблицы D:
| pnum | dname | dprice |
|---|---|---|
| 1 | Болт | 10 |
| 2 | Гайка | 20 |
| 3 | Винт | 30 |
Значения таблицы PD:
| pnum | dnum | volume |
|---|---|---|
| 1 | 1 | 100 |
| 1 | 2 | 100 |
| 1 | 3 | 300 |
| 2 | 1 | 150 |
| 1 | 2 | 250 |
| 3 | 1 | 1000 |
Блок помощи
Предложение SELECT
После служебного слова SELECT перечисляются имена столбцов, значения которых будут входить в результат выполнения запроса.
Если имя столбца содержит пробелы или разделители, то его необходимо заключить в квадратные скобки.
Предложение FROM
Пример 1.
Вывести список наименований деталей из таблицы D (“Детали”).
Пример 2.
Получить всю информацию из таблицы D (“Детали”).
Получить результат можно двумя способами:
В результате и первого и второго запроса получаем новую таблицу, представляющую собой полную копию таблицы D (“Детали”).
Можно осуществить выбор отдельных столбцов и их перестановку.
Пример 3.
Получить информацию о наименовании и номере поставщика.
Пример 4.
Определить номера поставщиков, которые поставляют детали в настоящее время (то есть номера тех поставщиков, которые присутствуют в таблице PD (“Поставки”)).
| pnum |
|---|
| 1 |
| 1 |
| 1 |
| 2 |
| 2 |
| 3 |
Дополнительно о SELECT
Агрегатные функции
В операторе SELECT можно использовать агрегатные функции, которые дают единственное значение для целой группы строк в таблице.
Агрегатная функция записывается в следующем виде: ( )
Пользователю доступны следующие агрегатные функции:
Пример 15.
Определить общий объем поставляемых деталей.
Столбцы результирующей таблицы, которых не существовало в исходных таблицах, называются вычисляемыми. Таким столбцам СУБД присваивает системные имена, что не всегда является удобным.
Следует запомнить, что агрегатные функции нельзя вкладывать друг в друга. Такая конструкция работать не будет: `MAX(SUM(VOLUME))`
Переименование столбца
Например, присвоить новое имя вычисляемому столбцу в предыдущем примере позволит выполнение следующего запроса.
Пример 16.
Определить количество поставщиков, которые поставляют детали в настоящее время.
Несмотря на то, что реальное число поставщиков деталей в таблице PD равно 3, СУБД возвращает число 6. Такой результат объясняется тем, что СУБД подсчитывает все строки в таблице PD, не обращая внимание на то, что в строках есть одинаковые значения.
Операция DISTINCT
Операция TOP
Итоговый набор записей, получаемых после выполнения запроса можно ограничить первыми N строками или первыми N процентами от общего количества строк результата.
Пример 23.
Определить номера первых двух деталей таблицы D.
Предложение WHERE
После служебного слова WHERE указываются условия выбора строк, помещаемых в результирующую таблицу. Существуют различные типы условий выбора:
Типы условий выбора:
Сравнение
Пример 5.
Определить номера деталей, поставляемых поставщиком с номером 2.
Пример 6.
Получить информацию о поставщиках Иванов и Петров.
Строковые значения атрибутов заключаются в апострофы.
Проверка на принадлежность множеству
Операция IN проверяет, принадлежит ли значение атрибута заданному множеству.
Пример 7.
Получить информацию о поставщиках ‘Иванов’ и ‘Петров’.
Пример 8.
Получить информацию о деталях с номерами 1 и 2.
Проверка на принадлежность диапазону
Операция BETWEEN определяет минимальную и максимальную границу диапазона, в которое должно попадать значение атрибута. Обе границы считаются принадлежащими диапазону.
Пример 9.
Определить номера деталей, с ценой от 10 до 20 рублей.
Пример 10.
Вывести наименования поставщиков, начинающихся с букв от ‘К’ по ‘П’.
Буква ‘Р’ в условии запроса объясняется тем, что строки сравниваются посимвольно. Для каждого символа при этом определяется код. Для нашего случая справедливо условие: ‘П’ LIKE используется для поиска подстрок. Значения столбца, указываемого перед служебным словом LIKE сравниваются с задаваемым после него шаблоном. Форматы шаблонов различаются в конкретных СУБД.
Для СУБД MS SQL Server:
Множество символов в квадратных скобках можно указывать через запятую, либо в виде диапазона.
Пример 11.
Вывести фамилии поставщиков, начинающихся с буквы ‘И’.
Пример 12.
Вывести фамилии поставщиков, начинающихся с букв от ‘К’ по ‘П’.
Проверка на наличие null-значения
Пример 13.
Определить наименования деталей, для которых не указана цена.
Пример 14.
Определить номера поставщиков, для которых указано наименование.
Предложение GROUP BY
Использование GROUP BY позволяет разбивать таблицу на логические группы и применять агрегатные функции к каждой из этих групп. В результате получим единственное значение для каждой группы.
Обычно предложение GROUP BY применяют, если формулировка задачи содержит фразу «для каждого…», «каждому..» и т.п.
Пример 18.
Определить суммарный объем деталей, поставляемых каждым поставщиком.
| pnum | sum |
|---|---|
| 1 | 600 |
| 2 | 400 |
| 3 | 1000 |
Выполнение запроса можно описать следующим образом: СУБД разбивает таблицу PD на три группы, в каждую из групп помещаются строки с одинаковым значением номера поставщика. Затем к каждой из полученных групп применяется агрегатная функция SUM, что дает единственное итоговое значение для каждой группы.
Рассмотрим два похожих примера.
В примере 1 определяется минимальный объем поставки каждого поставщика. В примере 2 определяется объем минимальной поставки среди всех поставщиков.
Результаты запросов представлены в следующей таблице:
| pnum | min | max |
|---|---|---|
| 1 | 100 | 100 |
| 2 | 150 | |
| 3 | 1000 |
Следует обратить внимание, что в первом примере мы можем вывести номера поставщиков, соответствующие объемам поставок, а во втором примере – не можем.
Пример 19.
Для каждой из деталей с номерами 1 и 2 определить количество поставщиков, которые их поставляют, а также суммарный объем поставок деталей.
| dnum | COUNT | SUM |
|---|---|---|
| 1 | 3 | 1250 |
| 2 | 2 | 450 |
Чтобы организовать вложенные группировки, после GROUP BY следует указать несколько группирующих столбцов через запятую. В этом случае реальный подсчет данных будет происходить по той группе, которая указана последней.
Предложение HAVING
Пример 20.
Определить номера поставщиков, поставляющих в сумме более 500 деталей.
| pnum | SUM |
|---|---|
| 1 | 600 |
| 3 | 1000 |
Пример 21.
Определить номера поставщиков, которые поставляют только одну деталь.
Предложение ORDER BY
При выполнении запроса СУБД возвращает строки в случайном порядке. Предложение ORDER BY позволяет упорядочить выходные данные запроса в соответствии со значениями одного или нескольких выбранных столбцов.
Пример 22.
Отсортировать таблицу PD в порядке возрастания номеров поставщиков, а строки с одинаковыми значениями pnum отсортировать в порядке убывания объема поставок.
| pnum | volume | dnum |
|---|---|---|
| 1 | 300 | 3 |
| 1 | 200 | 2 |
| 1 | 100 | 1 |
| 2 | 250 | 2 |
| 2 | 150 | 1 |
| 3 | 1000 | 1 |
Пример 24.
Определить номера первых двух деталей с наименьшей стоимостью.
Следует отметить, что если в таблице D будут две детали без указания цены, то именно их и отобразит предыдущий запрос.
Агрегатные функции нельзя применять в конструкции where
Выражениями значения являются:
Константа или непосредственное значение
Ссылка на позиционный параметр в теле определения функции или подготовленного оператора
Выражение с индексом
Выражение выбора поля
Вызов оконной функции
Применение правил сортировки
Конструктор табличной строки
Кроме того, выражением значения являются скобки (предназначенные для группировки подвыражений и переопределения приоритета )
Мы уже обсудили константы в Подразделе 4.1.2. В следующих разделах рассматриваются остальные варианты.
4.2.1. Ссылки на столбцы
Ссылку на столбец можно записать в форме:
4.2.2. Позиционные параметры
Ссылка на позиционный параметр применяется для обращения к значению, переданному в SQL-оператор извне. Параметры используются в определениях SQL-функций и подготовленных операторов. Некоторые клиентские библиотеки также поддерживают передачу значений данных отдельно от самой SQL-команды, и в этом случае параметры позволяют ссылаться на такие значения. Ссылка на параметр записывается в следующей форме:
Например, рассмотрим следующее определение функции dept :
4.2.3. Индексы элементов
Если в выражении вы имеете дело с массивом, то можно извлечь определённый его элемент, написав:
или несколько соседних элементов ( « срез массива » ):
(Здесь квадратные скобки [ ] должны присутствовать буквально.) Каждый индекс сам по себе является выражением, результат которого округляется к ближайшему целому.
В общем случае выражение массива должно заключаться в круглые скобки, но их можно опустить, когда выражение с индексом — это просто ссылка на столбец или позиционный параметр. Кроме того, можно соединить несколько индексов, если исходный массив многомерный. Например:
В последней строке круглые скобки необходимы. Подробнее массивы рассматриваются в Разделе 8.15.
4.2.4. Выбор поля
Если результат выражения — значение составного типа (строка таблицы), тогда определённое поле этой строки можно извлечь, написав:
В общем случае выражение такого типа должно заключаться в круглые скобки, но их можно опустить, когда это ссылка на таблицу или позиционный параметр. Например:
(Таким образом, полная ссылка на столбец — это просто частный случай выбора поля.) Важный особый случай здесь — извлечение поля из столбца составного типа:
Здесь скобки нужны, чтобы показать, что составной_столбец — это имя столбца, а не таблицы, и что моя_таблица — имя таблицы, а не схемы.
Эта запись действует по-разному в зависимости от контекста; подробнее об этом говорится в Подразделе 8.16.5.
4.2.5. Применение оператора
Существуют три возможных синтаксиса применения операторов:
| выражение оператор выражение (бинарный инфиксный оператор) |
| оператор выражение (унарный префиксный оператор) |
| выражение оператор (унарный постфиксный оператор) |
Существование конкретных операторов и их тип (унарный или бинарный) зависит от того, как и какие операторы определены системой и пользователем. Встроенные операторы описаны в Главе 9.
4.2.6. Вызовы функций
Вызов функции записывается просто как имя функции (возможно, дополненное именем схемы) и список аргументов в скобках:
Например, так вычисляется квадратный корень из 2:
Список встроенных функций приведён в Главе 9. Пользователь также может определить и другие функции.
Выполняя запросы в базе данных, где одни пользователи могут не доверять другим, в записи вызовов функций соблюдайте меры предосторожности, описанные в Разделе 10.3.
Аргументам могут быть присвоены необязательные имена. Подробнее об этом см. Раздел 4.3.
Примечание
4.2.7. Агрегатные выражения
Агрегатное выражение представляет собой применение агрегатной функции к строкам, выбранным запросом. Агрегатная функция сводит множество входных значений к одному выходному, как например, сумма или среднее. Агрегатное выражение может записываться следующим образом:
Здесь агрегатная_функция — имя ранее определённой агрегатной функции (возможно, дополненное именем схемы), выражение — любое выражение значения, не содержащее в себе агрегатного выражения или вызова оконной функции. Необязательные предложения предложение_order_by и условие_фильтра описываются ниже.
В первой форме агрегатного выражения агрегатная функция вызывается для каждой строки. Вторая форма эквивалентна первой, так как указание ALL подразумевается по умолчанию. В третьей форме агрегатная функция вызывается для всех различных значений выражения (или набора различных значений, для нескольких выражений), выделенных во входных данных. В четвёртой форме агрегатная функция вызывается для каждой строки, так как никакого конкретного значения не указано (обычно это имеет смысл только для функции count(*) ). В последней форме используются сортирующие агрегатные функции, которые будут описаны ниже.
Большинство агрегатных функций игнорируют значения NULL, так что строки, для которых выражения выдают одно или несколько значений NULL, отбрасываются. Это можно считать истинным для всех встроенных операторов, если явно не говорится об обратном.
Обычно строки данных передаются агрегатной функции в неопределённом порядке и во многих случаях это не имеет значения, например функция min выдаёт один и тот же результат независимо от порядка поступающих данных. Однако некоторые агрегатные функции (такие как array_agg и string_agg ) выдают результаты, зависящие от порядка данных. Для таких агрегатных функций можно добавить предложение_order_by и задать нужный порядок. Это предложение_order_by имеет тот же синтаксис, что и предложение ORDER BY на уровне запроса, как описано в Разделе 7.5, за исключением того, что его выражения должны быть просто выражениями, а не именами результирующих столбцов или числами. Например:
Заметьте, что при использовании агрегатных функций с несколькими аргументами, предложение ORDER BY идёт после всех аргументов. Например, надо писать так:
Последний вариант синтаксически допустим, но он представляет собой вызов агрегатной функции одного аргумента с двумя ключами ORDER BY (при этом второй не имеет смысла, так как это константа).
Примечание
Пример вызова сортирующей агрегатной функции:
Предопределённые агрегатные функции описаны в Разделе 9.20. Пользователь также может определить другие агрегатные функции.
Когда агрегатное выражение используется в подзапросе (см. Подраздел 4.2.11 и Раздел 9.22), оно обычно вычисляется для всех строк подзапроса. Но если в аргументах (или в условии_filter ) агрегатной функции есть только переменные внешнего уровня, агрегатная функция относится к ближайшему внешнему уровню и вычисляется для всех строк соответствующего запроса. Такое агрегатное выражение в целом является внешней ссылкой для своего подзапроса и на каждом вычислении считается константой. При этом допустимое положение агрегатной функции ограничивается списком результатов и предложением HAVING на том уровне запросов, где она находится.
4.2.8. Вызовы оконных функций
Вызов оконной функции представляет собой применение функции, подобной агрегатной, к некоторому набору строк, выбранному запросом. В отличие от вызовов не оконных агрегатных функций, они не связаны с группировкой выбранных строк в одну — каждая строка остаётся отдельной в результате запроса. Однако оконная функция имеет доступ ко всем строкам, вошедшим в группу текущей строки согласно указанию группировки (списку PARTITION BY ) в вызове оконной функции. Вызов оконной функции может иметь следующие формы:
Здесь определение_окна записывается в виде
и необязательное определение_рамки может иметь вид:
Здесь начало_рамки и конец_рамки задаются одним из следующих способов:
Здесь выражение — это любое выражение значения, не содержащее вызовов оконных функций.
Указание PARTITION BY группирует строки запроса в разделы, которые затем обрабатываются оконной функцией независимо друг от друга. PARTITION BY работает подобно предложению GROUP BY на уровне запроса, за исключением того, что его аргументы всегда просто выражения, а не имена выходных столбцов или числа. Без PARTITION BY все строки, выдаваемые запросом, рассматриваются как один раздел. Указание ORDER BY определяет порядок, в котором оконная функция обрабатывает строки раздела. Оно так же подобно предложению ORDER BY на уровне запроса и так же не принимает имена выходных столбцов или числа. Без ORDER BY строки обрабатываются в неопределённом порядке.
Встроенные оконные функции описаны в Таблице 9.57, но пользователь может расширить этот набор, создавая собственные функции. Кроме того, в качестве оконных функций можно использовать любые встроенные или пользовательские универсальные, а также статистические агрегатные функции. (Сортирующие и гипотезирующие агрегатные функции в настоящее время использовать в качестве оконных нельзя.)
Дополнительно об оконных функциях можно узнать в Разделе 3.5, Разделе 9.21 и Подразделе 7.2.5.
4.2.9. Приведения типов
Приведение типа определяет преобразование данных из одного типа в другой. Postgres Pro воспринимает две равносильные записи приведения типов:
Когда приведению подвергается значение выражения известного типа, происходит преобразование типа во время выполнения. Это приведение будет успешным, только если определён подходящий оператор преобразования типов. Обратите внимание на небольшое отличие от приведения констант, описанного в Подразделе 4.1.2.7. Приведение строки в чистом виде представляет собой начальное присваивание строковой константы и оно будет успешным для любого типа (конечно, если строка содержит значение, приемлемое для данного типа данных).
Неявное приведение типа можно опустить, если возможно однозначно определить, какой тип должно иметь выражение (например, когда оно присваивается столбцу таблицы); в таких случаях система автоматически преобразует тип. Однако автоматическое преобразование выполняется только для приведений с пометкой « допускается неявное применение » в системных каталогах. Все остальные приведения должны записываться явно. Это ограничение позволяет избежать сюрпризов с неявным преобразованием.
Также можно записать приведение типа как вызов функции:
Примечание
4.2.10. Применение правил сортировки
Предложение COLLATE переопределяет правило сортировки выражения. Оно добавляется после выражения:
где правило_сортировки — идентификатор правила, возможно дополненный именем схемы. Предложение COLLATE связывает выражение сильнее, чем операторы, так что при необходимости следует использовать скобки.
Если правило сортировки не определено явно, система либо выбирает его по столбцам, которые используются в выражении, либо, если таких столбцов нет, переключается на установленное для базы данных правило сортировки по умолчанию.
и переопределение правил сортировки при вызове функций или операторов, возвращающих языкозависимые результаты, например:
Но это будет ошибкой:
4.2.11. Скалярные подзапросы
Скалярный подзапрос — это обычный запрос SELECT в скобках, который возвращает ровно одну строку и один столбец. (Написание запросов освещается в Главе 7.) После выполнения запроса SELECT его единственный результат используется в окружающем его выражении. В качестве скалярного подзапроса нельзя использовать запросы, возвращающие более одной строки или столбца. (Но если в результате выполнения подзапрос не вернёт строк, скалярный результат считается равным NULL.) В подзапросе можно ссылаться на переменные из окружающего запроса; в процессе одного вычисления подзапроса они будут считаться константами. Другие выражения с подзапросами описаны в Разделе 9.22.
Например, следующий запрос находит самый населённый город в каждом штате:
4.2.12. Конструкторы массивов
По умолчанию типом элементов массива считается общий тип для всех выражений, определённый по правилам, действующим и для конструкций UNION и CASE (см. Раздел 10.5). Вы можете переопределить его явно, приведя конструктор массива к требуемому типу, например:
Это равносильно тому, что привести к нужному типу каждое выражение по отдельности. Подробнее приведение типов описано в Подразделе 4.2.9.
Многомерные массивы можно образовывать, вкладывая конструкторы массивов. При этом во внутренних конструкторах слово ARRAY можно опускать. Например, результат работы этих конструкторов одинаков:
Вы можете создать и пустой массив, но так как массив не может быть не типизированным, вы должны явно привести пустой массив к нужному типу. Например:
Такой подзапрос должен возвращать один столбец. Если этот столбец имеет тип, отличный от массива, результирующий одномерный массив будет включать элементы для каждой строки-результата подзапроса и типом элемента будет тип столбца результата. Если же тип столбца — массив, будет создан массив того же типа, но большей размерности; в любом случае во всех строках подзапроса должны выдаваться массивы одинаковой размерности, чтобы можно было получить прямоугольный результат.
4.2.13. Конструкторы табличных строк
Если в списке более одного выражения, ключевое слово ROW можно опустить.
Примечание
Подробнее см. Раздел 9.23. Конструкторы строк также могут использоваться в сочетании с подзапросами, как описано в Разделе 9.22.
4.2.14. Правила вычисления выражений
Порядок вычисления подвыражений не определён. В частности, аргументы оператора или функции не обязательно вычисляются слева направо или в любом другом фиксированном порядке.
Более того, если результат выражения можно получить, вычисляя только некоторые его части, тогда другие подвыражения не будут вычисляться вовсе. Например, если написать:
тогда функция somefunc() не будет вызываться (возможно). То же самое справедливо для записи:
Заметьте, что это отличается от « оптимизации » вычисления логических операторов слева направо, реализованной в некоторых языках программирования.
Когда порядок вычисления важен, его можно зафиксировать с помощью конструкции CASE (см. Раздел 9.17). Например, такой способ избежать деления на ноль в предложении WHERE ненадёжен:




