Введение в запросы в PostgreSQL

Вступление

Базы данных являются ключевым компонентом многих веб-сайтов и приложений и лежат в основе хранения и обмена данными в Интернете. Одним из наиболее важных аспектов управления базой данных является практика извлечения данных из базы данных, будь то на специальной основе или частью процесса, который был закодирован в приложении. Существует несколько способов получения информации из базы данных, но один из наиболее часто используемых методов выполняется путем отправки queries через командную строку.

В системах управления реляционными базами данных query - это любая команда, используемая для извлечения данных из таблицы. В языке структурированных запросов (SQL) запросы почти всегда выполняются с помощью оператора + SELECT +.

В этом руководстве мы обсудим базовый синтаксис запросов SQL, а также некоторые из наиболее часто используемых функций и операторов. Мы также будем практиковаться в создании запросов SQL с использованием некоторых примеров данных в базе данных PostgreSQL.

PostgreSQL, часто сокращаемая до «Postgres», представляет собой систему управления реляционными базами данных с объектно-ориентированным подходом, что означает, что информация может быть представлена ​​в виде объектов или классов в схемах PostgreSQL. PostgreSQL тесно связан со стандартным SQL, хотя он также включает некоторые функции, которых нет в других системах реляционных баз данных.

Предпосылки

В общем, команды и концепции, представленные в этом руководстве, могут использоваться в любой операционной системе на базе Linux, на которой работает любое программное обеспечение базы данных SQL. Тем не менее, он был написан специально для сервера Ubuntu 18.04, использующего PostgreSQL. Для настройки вам понадобится следующее:

С этой настройкой мы можем начать учебник.

Создание образца базы данных

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

Для примера базы данных, которую мы будем использовать в этом руководстве, представьте следующий сценарий:

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

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

Для начала откройте приглашение PostgreSQL от имени своего * postgres * суперпользователя:

sudo -u postgres psql

Затем создайте базу данных, запустив:

CREATE DATABASE birthdays;

Затем выберите эту базу данных, набрав:

\c birthdays

Затем создайте две таблицы в этой базе данных. Мы будем использовать первую таблицу, чтобы отслеживать записи ваших друзей в боулинге. Следующая команда создаст таблицу с именем + tourneys + со столбцами для + name + каждого из ваших друзей, количества выигранных ими турниров (+ wins +), их общего рейтинга + best + и какой размер обуви для боулинга они носят (+ размер +):

CREATE TABLE tourneys (
name varchar(30),
wins real,
best real,
size real
);

После того, как вы запустите команду + CREATE TABLE и заполните ее заголовками столбцов, вы получите следующий вывод:

OutputCREATE TABLE

Заполните таблицу + tourneys + некоторыми примерами данных:

INSERT INTO tourneys (name, wins, best, size)
VALUES ('Dolly', '7', '245', '8.5'),
('Etta', '4', '283', '9'),
('Irma', '9', '266', '7'),
('Barbara', '2', '197', '7.5'),
('Gladys', '13', '273', '8');

Вы получите следующий вывод:

OutputINSERT 0 5

После этого создайте еще одну таблицу в той же базе данных, которую мы будем использовать для хранения информации о любимых блюдах ваших друзей на день рождения. Следующая команда создает таблицу с именем + dinners + со столбцами для + name + каждого из ваших друзей, их + birthdate +, их любимых + entree +, их предпочтительных блюд + side + и их любимых ` + десерт + `:

CREATE TABLE dinners (
name varchar(30),
birthdate date,
entree varchar(30),
side varchar(30),
dessert varchar(30)
);

Аналогично для этой таблицы вы получите отзыв о том, что таблица была создана:

OutputCREATE TABLE

Заполните эту таблицу также некоторыми примерами данных:

INSERT INTO dinners (name, birthdate, entree, side, dessert)
VALUES ('Dolly', '1946-01-19', 'steak', 'salad', 'cake'),
('Etta', '1938-01-25', 'chicken', 'fries', 'ice cream'),
('Irma', '1941-02-18', 'tofu', 'fries', 'cake'),
('Barbara', '1948-12-25', 'tofu', 'salad', 'ice cream'),
('Gladys', '1944-05-28', 'steak', 'fries', 'ice cream');
OutputINSERT 0 5

Как только эта команда завершится успешно, вы закончили настройку базы данных. Далее мы рассмотрим базовую структуру команд запросов + SELECT +.

Понимание утверждений SELECT

Как упоминалось во введении, SQL-запросы почти всегда начинаются с оператора + SELECT +. + SELECT + используется в запросах, чтобы указать, какие столбцы из таблицы должны быть возвращены в наборе результатов. Запросы также почти всегда включают + FROM +, который используется для указания таблицы, которую запрос будет запрашивать оператор.

Как правило, SQL-запросы следуют этому синтаксису:

SELECT  FROM  WHERE ;

Например, следующий оператор вернет весь столбец + name + из таблицы + dinners +:

SELECT name FROM dinners;
Output  name
---------
Dolly
Etta
Irma
Barbara
Gladys
(5 rows)

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

SELECT name, birthdate FROM dinners;
Output  name   | birthdate
---------+------------
Dolly   | 1946-01-19
Etta    | 1938-01-25
Irma    | 1941-02-18
Barbara | 1948-12-25
Gladys  | 1944-05-28
(5 rows)

Вместо того, чтобы называть конкретный столбец или набор столбцов, вы можете следовать за оператором + SELECT + со звездочкой (+ * +), которая служит заполнителем, представляющим все столбцы в таблице. Следующая команда возвращает каждый столбец из таблицы + tourneys +:

SELECT * FROM tourneys;
Output  name   | wins | best | size
---------+------+------+------
Dolly   |    7 |  245 |  8.5
Etta    |    4 |  283 |    9
Irma    |    9 |  266 |    7
Barbara |    2 |  197 |  7.5
Gladys  |   13 |  273 |    8
(5 rows)

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

. . . WHERE

Оператор сравнения в предложении + WHERE + определяет способ сравнения указанного столбца со значением. Вот некоторые распространенные операторы сравнения SQL:

Operator What it does

=

tests for equality

!=

tests for inequality

<

tests for less-than

>

tests for greater-than

<=

tests for less-than or equal-to

>=

tests for greater-than or equal-to

BETWEEN

tests whether a value lies within a given range

IN

tests whether a row’s value is contained in a set of specified values

EXISTS

tests whether rows exist, given the specified conditions

LIKE

tests whether a value matches a specified string

IS NULL

tests for NULL values

IS NOT NULL

tests for all values other than NULL

Например, если вы хотите найти размер обуви Ирмы, вы можете использовать следующий запрос:

SELECT size FROM tourneys WHERE name = 'Irma';
Output size
------
   7
(1 row)

SQL допускает использование подстановочных знаков, и это особенно удобно при использовании в предложениях + WHERE +. Знаки процента (+% +) представляют ноль или более неизвестных символов, а подчеркивания (+ _ +) представляют один неизвестный символ. Они полезны, если вы пытаетесь найти конкретную запись в таблице, но не уверены, что именно это за запись. Для иллюстрации предположим, что вы забыли любимую запись нескольких своих друзей, но уверены, что эта запись начинается с буквы «т». Вы можете найти ее имя, выполнив следующий запрос:

SELECT entree FROM dinners WHERE entree LIKE 't%';
Output entree
-------
tofu
tofu
(2 rows)

Основываясь на вышеприведенном выводе, мы видим, что забытая запись - + tofu +.

Могут быть случаи, когда вы работаете с базами данных, в которых есть столбцы или таблицы с относительно длинными или трудно читаемыми именами. В этих случаях вы можете сделать эти имена более читабельными, создав псевдоним с ключевым словом + AS +. Псевдонимы, созданные с помощью + AS +, являются временными и существуют только на время запроса, для которого они созданы:

SELECT name AS n, birthdate AS b, dessert AS d FROM dinners;
Output    n    |     b      |     d
---------+------------+-----------
Dolly   | 1946-01-19 | cake
Etta    | 1938-01-25 | ice cream
Irma    | 1941-02-18 | cake
Barbara | 1948-12-25 | ice cream
Gladys  | 1944-05-28 | ice cream
(5 rows)

Здесь мы указали SQL отображать столбец + name + как + n +, столбец + birthdate + как + b +, а столбец + десерт + как + d +.

Примеры, которые мы рассмотрели до этого момента, включают некоторые из наиболее часто используемых ключевых слов и предложений в запросах SQL. Они полезны для базовых запросов, но они бесполезны, если вы пытаетесь выполнить вычисление или получить скалярное значение (одно значение, а не набор из нескольких различных значений) на основе ваших данных. Это где агрегатные функции вступают в игру.

Агрегатные функции

Часто при работе с данными вам не обязательно видеть сами данные. Скорее, вам нужна информация о данных. Синтаксис SQL включает в себя ряд функций, которые позволяют вам интерпретировать или выполнять вычисления на ваших данных, просто выполнив запрос + SELECT +. Они известны как aggregate functions.

Функция + COUNT + считает и возвращает количество строк, соответствующих определенным критериям. Например, если вы хотите узнать, сколько ваших друзей предпочитают тофу для своего дня рождения, вы можете выполнить этот запрос:

SELECT COUNT(entree) FROM dinners WHERE entree = 'tofu';
Output count
-------
    2
(1 row)

Функция + AVG + возвращает среднее (среднее) значение столбца. Используя наш пример таблицы, вы можете найти средний лучший результат среди ваших друзей с этим запросом:

SELECT AVG(best) FROM tourneys;
Output  avg
-------
252.8
(1 row)

+ SUM + используется для нахождения общей суммы данного столбца. Например, если вы хотите посмотреть, сколько игр вы и ваши друзья играли в боулинг за эти годы, вы можете выполнить этот запрос:

SELECT SUM(wins) FROM tourneys;
Output sum
-----
 35
(1 row)

Обратите внимание, что функции + AVG + и + SUM + будут работать правильно только при использовании с числовыми данными. Если вы попытаетесь использовать их для нечисловых данных, это приведет к ошибке или просто «+ 0 +», в зависимости от того, какую СУБД вы используете:

SELECT SUM(entree) FROM dinners;
OutputERROR:  function sum(character varying) does not exist
LINE 1: select sum(entree) from dinners;
              ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

+ MIN + используется для поиска наименьшего значения в указанном столбце. Вы можете использовать этот запрос, чтобы увидеть, какой худший из всех боулинг-рекордов (с точки зрения количества побед):

SELECT MIN(wins) FROM tourneys;
Output min
-----
  2
(1 row)

Аналогично, + MAX + используется для поиска наибольшего числового значения в данном столбце. Следующий запрос покажет лучший общий результат в боулинге:

SELECT MAX(wins) FROM tourneys;
Output max
-----
 13
(1 row)

В отличие от + SUM и` + AVG`, функции + MIN и` + MAX` могут использоваться как для числовых, так и для буквенных типов данных. При запуске в столбце, содержащем строковые значения, функция + MIN + покажет первое значение в алфавитном порядке:

SELECT MIN(name) FROM dinners;
Output   min
---------
Barbara
(1 row)

Аналогично, при запуске столбца, содержащего строковые значения, функция + MAX + покажет последнее значение в алфавитном порядке:

SELECT MAX(name) FROM dinners;
Output max
------
Irma
(1 row)

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

Манипуляции с результатами запросов

В дополнение к предложениям + FROM и` + WHERE`, есть несколько других предложений, которые используются для манипулирования результатами запроса + SELECT +. В этом разделе мы объясним и предоставим примеры для некоторых из наиболее часто используемых предложений запросов.

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

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

SELECT COUNT(name), entree FROM dinners GROUP BY entree;
Output count | entree
-------+---------
    1 | chicken
    2 | steak
    2 | tofu
(3 rows)

Предложение + ORDER BY используется для сортировки результатов запроса. По умолчанию числовые значения сортируются в порядке возрастания, а текстовые значения сортируются в алфавитном порядке. Для иллюстрации следующий запрос перечисляет столбцы + name и` + birthdate`, но сортирует результаты по дате рождения:

SELECT name, birthdate FROM dinners ORDER BY birthdate;
Output  name   | birthdate
---------+------------
Etta    | 1938-01-25
Irma    | 1941-02-18
Gladys  | 1944-05-28
Dolly   | 1946-01-19
Barbara | 1948-12-25
(5 rows)

Обратите внимание, что стандартное поведение + ORDER BY + заключается в сортировке результирующего набора в порядке возрастания. Чтобы отменить это и отсортировать результирующий набор в порядке убывания, закройте запрос с помощью + DESC +:

SELECT name, birthdate FROM dinners ORDER BY birthdate DESC;
Output  name   | birthdate
---------+------------
Barbara | 1948-12-25
Dolly   | 1946-01-19
Gladys  | 1944-05-28
Irma    | 1941-02-18
Etta    | 1938-01-25
(5 rows)

Как упоминалось ранее, предложение + WHERE + используется для фильтрации результатов на основе определенных условий. Однако, если вы используете предложение + WHERE + с агрегатной функцией, оно вернет ошибку, как в случае со следующей попыткой определить, какие стороны являются фаворитами по крайней мере трех ваших друзей:

SELECT COUNT(name), side FROM dinners WHERE COUNT(name) >= 3;
OutputERROR:  aggregate functions are not allowed in WHERE
LINE 1: SELECT COUNT(name), side FROM dinners WHERE COUNT(name) >= 3...

Предложение + HAVING + было добавлено в SQL, чтобы обеспечить функциональность, аналогичную предложению + WHERE +, а также совместимость с агрегатными функциями. Полезно думать о разнице между этими двумя пунктами как о том, что + WHERE + применяется к отдельным записям, в то время как + HAVING + применяется к групповым записям. С этой целью каждый раз, когда вы вводите предложение + HAVING, также должно присутствовать предложение` + GROUP BY`.

Следующий пример - еще одна попытка найти, какие гарниры являются фаворитами как минимум трех ваших друзей, хотя этот вернет результат без ошибок:

SELECT COUNT(name), side FROM dinners GROUP BY side HAVING COUNT(name) >= 3;
Output count | side
-------+-------
    3 | fries
(1 row)

Агрегатные функции полезны для суммирования результатов конкретного столбца в данной таблице. Однако во многих случаях необходимо запросить содержимое более чем одной таблицы. Мы рассмотрим несколько способов сделать это в следующем разделе.

Запрос нескольких таблиц

Чаще всего база данных содержит несколько таблиц, каждая из которых содержит разные наборы данных. SQL предоставляет несколько разных способов выполнения одного запроса для нескольких таблиц.

Предложение + JOIN + может использоваться для объединения строк из двух или более таблиц в результате запроса. Это достигается путем нахождения связанного столбца между таблицами и надлежащим образом сортирует результаты в выходных данных.

Операторы + SELECT +, которые включают предложение + JOIN +, обычно следуют этому синтаксису:

SELECT ., .
FROM
JOIN  ON .=.;

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

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

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
JOIN dinners ON tourneys.name=dinners.name;
Output  name   | size | birthdate
---------+------+------------
Dolly   |  8.5 | 1946-01-19
Etta    |    9 | 1938-01-25
Irma    |    7 | 1941-02-18
Barbara |  7.5 | 1948-12-25
Gladys  |    8 | 1944-05-28
(5 rows)

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

INSERT INTO tourneys (name, wins, best, size)
VALUES ('Bettye', '0', '193', '9');
INSERT INTO dinners (name, birthdate, entree, side, dessert)
VALUES ('Lesley', '1946-05-02', 'steak', 'salad', 'ice cream');

Затем повторно запустите предыдущий оператор + SELECT с предложением` + JOIN`:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
JOIN dinners ON tourneys.name=dinners.name;
Output  name   | size | birthdate
---------+------+------------
Dolly   |  8.5 | 1946-01-19
Etta    |    9 | 1938-01-25
Irma    |    7 | 1941-02-18
Barbara |  7.5 | 1948-12-25
Gladys  |    8 | 1944-05-28
(5 rows)

Обратите внимание, что, поскольку таблица + tourneys + не имеет записи для Лесли, а таблица + dinners + не имеет записи для Бетти, эти записи отсутствуют в этих выходных данных.

Тем не менее, можно вернуть все записи из одной из таблиц, используя предложение outer + JOIN +. Внешние предложения + JOIN + записываются как + LEFT JOIN +, + RIGHT JOIN + или + FULL JOIN +.

Предложение + LEFT JOIN + возвращает все записи из «левой» таблицы и только совпадающие записи из правой таблицы. В контексте внешних объединений левая таблица - это таблица, на которую ссылается условие + FROM +, а правая таблица - любая другая таблица, на которую ссылается после оператора + JOIN +.

Выполните предыдущий запрос еще раз, но на этот раз используйте предложение + LEFT JOIN +:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
LEFT JOIN dinners ON tourneys.name=dinners.name;

Эта команда будет возвращать каждую запись из левой таблицы (в данном случае + tourneys +), даже если у нее нет соответствующей записи в правой таблице. Каждый раз, когда в правой таблице нет подходящей записи, она возвращается как пустое значение или + NULL +, в зависимости от вашей РСУБД:

Output  name   | size | birthdate
---------+------+------------
Dolly   |  8.5 | 1946-01-19
Etta    |    9 | 1938-01-25
Irma    |    7 | 1941-02-18
Barbara |  7.5 | 1948-12-25
Gladys  |    8 | 1944-05-28
Bettye  |    9 |
(6 rows)

Теперь снова запустите запрос, на этот раз с предложением + RIGHT JOIN +:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
RIGHT JOIN dinners ON tourneys.name=dinners.name;

Это вернет все записи из правой таблицы (+ dinners +). Поскольку дата рождения Лесли записана в правой таблице, но для нее нет соответствующей строки в левой таблице, столбцы + name + и + size + вернутся как пустые значения в этой строке:

Output  name   | size | birthdate
---------+------+------------
Dolly   |  8.5 | 1946-01-19
Etta    |    9 | 1938-01-25
Irma    |    7 | 1941-02-18
Barbara |  7.5 | 1948-12-25
Gladys  |    8 | 1944-05-28
        |      | 1946-05-02
(6 rows)

Обратите внимание, что левые и правые объединения могут быть записаны как + LEFT OUTER JOIN + или + RIGHT OUTER JOIN +, хотя подразумевается часть + OUTER + в предложении. Аналогично, указание + INNER JOIN даст тот же результат, что и простое написание` + JOIN`.

Для некоторых дистрибутивов RDBMS, в том числе PostgreSQL, существует четвертое условие соединения, называемое + FULL JOIN +. + FULL JOIN + вернет все записи из каждой таблицы, включая любые нулевые значения:

SELECT tourneys.name, tourneys.size, dinners.birthdate
FROM tourneys
FULL JOIN dinners ON tourneys.name=dinners.name;
Output  name   | size | birthdate
---------+------+------------
Dolly   |  8.5 | 1946-01-19
Etta    |    9 | 1938-01-25
Irma    |    7 | 1941-02-18
Barbara |  7.5 | 1948-12-25
Gladys  |    8 | 1944-05-28
Bettye  |    9 |
        |      | 1946-05-02
(7 rows)

В качестве альтернативы использованию + FULL JOIN + для запроса всех записей из нескольких таблиц, вы можете использовать предложение + UNION +.

Оператор + UNION + работает немного иначе, чем предложение + JOIN +: вместо вывода результатов из нескольких таблиц в виде уникальных столбцов с использованием одного оператора + SELECT +, + UNION + объединяет результаты двух операторов + SELECT + в один столбец.

Для иллюстрации выполните следующий запрос:

SELECT name FROM tourneys UNION SELECT name FROM dinners;

Этот запрос удалит все повторяющиеся записи, что является поведением по умолчанию оператора + UNION:

Output  name
---------
Irma
Etta
Bettye
Gladys
Barbara
Lesley
Dolly
(7 rows)

Чтобы вернуть все записи (включая дубликаты), используйте оператор + UNION ALL +:

SELECT name FROM tourneys UNION ALL SELECT name FROM dinners;
Output  name
---------
Dolly
Etta
Irma
Barbara
Gladys
Bettye
Dolly
Etta
Irma
Barbara
Gladys
Lesley
(12 rows)

Имена и количество столбцов в таблице результатов отражают имя и количество столбцов, запрошенных первым оператором + SELECT +. Обратите внимание, что при использовании + UNION + для запроса нескольких столбцов из более чем одной таблицы каждый оператор + SELECT + должен запрашивать одинаковое количество столбцов, соответствующие столбцы должны иметь одинаковые типы данных, а столбцы в каждом + SELECT + Заявление должно быть в том же порядке. В следующем примере показано, что может произойти, если вы используете предложение + UNION для двух операторов` + SELECT`, которые запрашивают разное количество столбцов:

SELECT name FROM dinners UNION SELECT name, wins FROM tourneys;
OutputERROR:  each UNION query must have the same number of columns
LINE 1: SELECT name FROM dinners UNION SELECT name, wins FROM tourne...

Другой способ запроса нескольких таблиц - использование subqueries. Подзапросы (также известные как inner или nested query) - это запросы, заключенные в другой запрос. Это полезно в тех случаях, когда вы пытаетесь отфильтровать результаты запроса по сравнению с результатами отдельной агрегатной функции.

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

SELECT name, wins FROM tourneys
WHERE wins > (
SELECT wins FROM tourneys WHERE name = 'Barbara'
);
Output  name  | wins
--------+------
Dolly  |    7
Etta   |    4
Irma   |    9
Gladys |   13
(4 rows)

Подзапрос в этом операторе был выполнен только один раз; нужно только найти значение из столбца + wins + в той же строке, что и + Barbara + в столбце + name +, и данные, возвращаемые подзапросом и внешним запросом, не зависят друг от друга. Однако существуют случаи, когда внешний запрос должен сначала прочитать каждую строку в таблице и сравнить эти значения с данными, возвращенными подзапросом, чтобы получить требуемые данные. В этом случае подзапрос называется коррелированным подзапросом.

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

SELECT name, size FROM tourneys AS t
WHERE wins > (
SELECT AVG(wins) FROM tourneys WHERE size = t.size
);

Чтобы запрос завершился, он должен сначала собрать столбцы + names и` + size of` из внешнего запроса. Затем он сравнивает каждую строку из этого набора результатов с результатами внутреннего запроса, который определяет среднее количество побед для людей с одинаковыми размерами обуви. Поскольку у вас есть только два друга с одинаковым размером обуви, в наборе результатов может быть только одна строка:

Output name | size
------+------
Etta |    9
(1 row)

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

SELECT name, entree, side, dessert
FROM dinners
WHERE name = (SELECT name FROM tourneys
WHERE wins = (SELECT MAX(wins) FROM tourneys));
Output  name  | entree | side  |  dessert
--------+--------+-------+-----------
Gladys | steak  | fries | ice cream
(1 row)

Обратите внимание, что этот оператор не только включает подзапрос, но также содержит подзапрос в этом подзапросе.

Заключение

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

Если вы новичок в работе с SQL, мы рекомендуем вам использовать наш SQL шпаргалку в качестве ссылаться и просматривать official документов PostgreSQL. Кроме того, если вы хотите больше узнать о SQL и реляционных базах данных, вам могут быть интересны следующие учебные пособия:

Related