Поиск…
Вступление
Оператор SELECT лежит в основе большинства SQL-запросов. Он определяет, какой результат должен быть возвращен запросом, и почти всегда используется в сочетании с предложением FROM, которое определяет, какую часть (ы) базы данных следует запрашивать.
Синтаксис
SELECT [DISTINCT] [column1] [, [column2] ...]
FROM [таблица]
[ГДЕ условие]
[GROUP BY [column1] [, [column2] ...][HAVING [column1] [, [column2] ...]
[ORDER BY ASC | DESC]
замечания
SELECT определяет, какие данные столбцов будут возвращены и в каком порядке из данной таблицы (при условии, что они соответствуют другим требованиям в вашем запросе конкретно - где и с фильтрами и объединениями).
SELECT Name, SerialNumber
FROM ArmyInfo
будут возвращать результаты только из столбцов Name
и Serial Number
, но не из столбца Rank
, например
SELECT *
FROM ArmyInfo
указывает, что все столбцы будут возвращены. Однако учтите, что это низкая практика SELECT *
поскольку вы буквально возвращаете все столбцы таблицы.
Использование символа подстановки для выбора всех столбцов в запросе.
Рассмотрим базу данных со следующими двумя таблицами.
Таблица сотрудников:
Я бы | FName | LName | DeptId |
---|---|---|---|
1 | Джеймс | кузнец | 3 |
2 | Джон | Джонсон | 4 |
Таблица отделов:
Я бы | название |
---|---|
1 | Продажи |
2 | маркетинг |
3 | финансов |
4 | ЭТО |
Операция простого выбора
*
- это символ подстановки, используемый для выбора всех доступных столбцов в таблице.
При использовании в качестве замены явных имен столбцов он возвращает все столбцы во всех таблицах, которые запрос выбирает FROM
. Этот эффект применяется ко всем таблицам, к которым обращается запрос через его предложения JOIN
.
Рассмотрим следующий запрос:
SELECT * FROM Employees
Он вернет все поля всех строк таблицы Employees
:
Я бы | FName | LName | DeptId |
---|---|---|---|
1 | Джеймс | кузнец | 3 |
2 | Джон | Джонсон | 4 |
Точечная нотация
Чтобы выбрать все значения из конкретной таблицы, подстановочный знак можно применить к таблице с точечной нотацией .
Рассмотрим следующий запрос:
SELECT
Employees.*,
Departments.Name
FROM
Employees
JOIN
Departments
ON Departments.Id = Employees.DeptId
Это вернет набор данных со всеми полями в таблице Employee
, а затем просто поле Name
в таблице Departments
:
Я бы | FName | LName | DeptId | название |
---|---|---|---|---|
1 | Джеймс | кузнец | 3 | финансов |
2 | Джон | Джонсон | 4 | ЭТО |
Предупреждения против использования
Как правило, рекомендуется использовать *
в производственном коде, где это возможно, поскольку это может вызвать ряд потенциальных проблем, в том числе:
- Избыток ввода-вывода, загрузка сети, использование памяти и т. Д. Из-за того, что данные базы данных не считывают данные и не передают их интерфейсу. Это особенно опасно, когда могут быть большие поля, такие как те, которые используются для хранения длинных заметок или прикрепленных файлов.
- Дальнейшая избыточная загрузка ввода-вывода, если базе данных необходимо спутать внутренние результаты на диск как часть обработки запроса более сложным, чем
SELECT <columns> FROM <table>
. - Дополнительная обработка (и / или даже больше ввода-вывода), если некоторые из ненужных столбцов:
- вычисляемые столбцы в базах данных, которые их поддерживают
- в случае выбора из представления столбцы из таблицы / представления, которые оптимизатор запросов мог бы в противном случае оптимизировать
- Потенциал неожиданных ошибок, если столбцы добавляются к таблицам и представлениям позже, приводит к неоднозначным именам столбцов. Например,
SELECT * FROM orders JOIN people ON people.id = orders.personid ORDER BY displayname
- если столбец столбца с именемdisplayname
добавлен в таблицу заказов, чтобы пользователи могли давать свои заказы значимых имен для будущей ссылки, тогда появится имя столбца дважды на выходе, поэтому предложениеORDER BY
будет неоднозначным, что может привести к ошибкам («неоднозначное имя столбца» в последних версиях MS SQL Server), и если не в этом примере, ваш код приложения может начать отображать имя заказа, в котором имя человека потому что новый столбец является первым из этого имени, и так далее.
Когда вы можете использовать *
, принимая предупреждение выше?
Несмотря на то, что в производственном коде лучше всего избегать, использование *
отлично подходит для выполнения ручных запросов к базе данных для исследования или работы прототипа.
Иногда проектные решения в вашей заявке делают ее неизбежной (в таких обстоятельствах предпочитают tablealias.*
по возможности *
возможности).
При использовании EXISTS
, таких как SELECT A.col1, A.Col2 FROM A WHERE EXISTS (SELECT * FROM B where A.ID = B.A_ID)
, мы не возвращаем никаких данных из B. Таким образом, соединение не нужно, и двигатель знает, что никакие значения из B не должны быть возвращены, поэтому при использовании *
. Аналогично COUNT(*)
является прекрасным, так как он также фактически не возвращает ни один из столбцов, поэтому нужно только читать и обрабатывать те, которые используются для целей фильтрации.
Выбор с условием
Основной синтаксис предложения SELECT с предложением WHERE:
SELECT column1, column2, columnN
FROM table_name
WHERE [condition]
[Condition] может быть любым выражением SQL, указанным с использованием сравнительных или логических операторов, таких как>, <, =, <>,> =, <=, LIKE, NOT, IN, BETWEEN и т. Д.
Следующий оператор возвращает все столбцы из таблицы «Автомобили», где столбец состояния «ГОТОВ»:
SELECT * FROM Cars WHERE status = 'READY'
См. WHERE и HAVING для получения дополнительных примеров.
Выберите отдельные столбцы
SELECT
PhoneNumber,
Email,
PreferredContact
FROM Customers
Этот оператор возвращает столбцы PhoneNumber
, Email
и PreferredContact
из всех строк таблицы Customers
. Также столбцы будут возвращены в последовательности, в которой они отображаются в предложении SELECT
.
Результатом будет:
Номер телефона | Эл. адрес | PreferredContact |
---|---|---|
3347927472 | [email protected] | ТЕЛЕФОН |
2137921892 | [email protected] | ЭЛ. АДРЕС |
НОЛЬ | [email protected] | ЭЛ. АДРЕС |
Если несколько таблиц объединены вместе, вы можете выбрать столбцы из определенных таблиц, указав имя таблицы перед именем столбца: [table_name].[column_name]
SELECT
Customers.PhoneNumber,
Customers.Email,
Customers.PreferredContact,
Orders.Id AS OrderId
FROM
Customers
LEFT JOIN
Orders ON Orders.CustomerId = Customers.Id
* AS OrderId
означает, что поле Id
таблицы Orders
будет возвращено в виде столбца с именем OrderId
. Для получения дополнительной информации см. Выбор с помощью псевдонима столбца .
Чтобы избежать использования имен длинных таблиц, вы можете использовать псевдонимы таблиц. Это уменьшает боль при написании длинных имен таблиц для каждого поля, которое вы выбираете в объединениях. Если вы выполняете самостоятельное соединение (соединение между двумя экземплярами одной и той же таблицы), вы должны использовать псевдонимы таблиц, чтобы отличать ваши таблицы. Мы можем написать псевдоним таблицы, такой как Customers c
или Customers AS c
. Здесь c
работает как псевдоним для Customers
и мы можем выбрать, скажем, по Email
: c.Email
.
SELECT
c.PhoneNumber,
c.Email,
c.PreferredContact,
o.Id AS OrderId
FROM
Customers c
LEFT JOIN
Orders o ON o.CustomerId = c.Id
SELECT Использование псевдонимов столбцов
Алиасы столбцов используются, главным образом, для сокращения кода и создания более удобных имен столбцов.
Код становится короче, как длинные имена таблиц и ненужная идентификация столбцов (например, в таблице может быть 2 идентификатора, но только один из них используется в инструкции) . Наряду с псевдонимами таблиц это позволяет использовать более длинные описательные имена в структуре вашей базы данных, сохраняя при этом запросы в этой структуре краткими.
Кроме того, они иногда требуются , например, в представлениях, чтобы назвать вычисленные выходы.
Все версии SQL
Псевдонимы могут быть созданы во всех версиях SQL с использованием двойных кавычек ( "
).
SELECT
FName AS "First Name",
MName AS "Middle Name",
LName AS "Last Name"
FROM Employees
Различные версии SQL
Вы можете использовать одинарные кавычки ( '
), двойные кавычки ( "
) и квадратные скобки ( []
) для создания псевдонима в Microsoft SQL Server.
SELECT
FName AS "First Name",
MName AS 'Middle Name',
LName AS [Last Name]
FROM Employees
Оба приведут к:
Имя | Второе имя | Фамилия |
---|---|---|
Джеймс | Джон | кузнец |
Джон | Джеймс | Джонсон |
Майкл | Маркус | Williams |
Этот оператор возвращает столбцы FName
и LName
с заданным именем (псевдоним). Это достигается с помощью оператора AS
за которым следует псевдоним, или просто записывая псевдоним непосредственно после имени столбца. Это означает, что следующий запрос имеет тот же результат, что и выше.
SELECT
FName "First Name",
MName "Middle Name",
LName "Last Name"
FROM Employees
Имя | Второе имя | Фамилия |
---|---|---|
Джеймс | Джон | кузнец |
Джон | Джеймс | Джонсон |
Майкл | Маркус | Williams |
Однако явная версия (т. Е. Использование оператора AS
) более читаема.
Если псевдоним имеет одно слово, которое не является зарезервированным словом, мы можем записать его без одинарных кавычек, двойных кавычек или скобок:
SELECT
FName AS FirstName,
LName AS LastName
FROM Employees
Имя | Фамилия |
---|---|
Джеймс | кузнец |
Джон | Джонсон |
Майкл | Williams |
Еще один вариант, доступный в MS SQL Server, - это <alias> = <column-or-calculation>
, например:
SELECT FullName = FirstName + ' ' + LastName,
Addr1 = FullStreetAddress,
Addr2 = TownName
FROM CustomerDetails
что эквивалентно:
SELECT FirstName + ' ' + LastName As FullName
FullStreetAddress As Addr1,
TownName As Addr2
FROM CustomerDetails
Оба приведут к:
ФИО | Addr1 | Addr2 |
---|---|---|
Джеймс Смит | 123 AnyStreet | TownVille |
Джон Джонсон | 668 MyRoad | Anytown |
Майкл Уильямс | 999 High End Dr | Williamsburgh |
Некоторые находят использование =
вместо того, чтобы читать As
легче, хотя многие рекомендуют этот формат, главным образом потому, что он не является стандартным, поэтому не поддерживается всеми базами данных. Это может привести к путанице с другими использованиями символа =
.
Все версии SQL
Кроме того, если вам нужно использовать зарезервированные слова, вы можете использовать скобки или кавычки для выхода:
SELECT
FName as "SELECT",
MName as "FROM",
LName as "WHERE"
FROM Employees
Различные версии SQL
Аналогично, вы можете избежать ключевых слов в MSSQL со всеми различными подходами:
SELECT
FName AS "SELECT",
MName AS 'FROM',
LName AS [WHERE]
FROM Employees
ВЫБРАТЬ | ОТ | ГДЕ |
---|---|---|
Джеймс | Джон | кузнец |
Джон | Джеймс | Джонсон |
Майкл | Маркус | Williams |
Кроме того, псевдоним столбца может использоваться любым из заключительных предложений одного и того же запроса, например ORDER BY
:
SELECT
FName AS FirstName,
LName AS LastName
FROM
Employees
ORDER BY
LastName DESC
Однако вы не можете использовать
SELECT
FName AS SELECT,
LName AS FROM
FROM
Employees
ORDER BY
LastName DESC
Чтобы создать псевдоним из этих зарезервированных слов ( SELECT
и FROM
).
Это вызовет многочисленные ошибки при выполнении.
Выбор с отсортированными результатами
SELECT * FROM Employees ORDER BY LName
Этот оператор вернет все столбцы из таблицы Employees
.
Я бы | FName | LName | Номер телефона |
---|---|---|---|
2 | Джон | Джонсон | 2468101214 |
1 | Джеймс | кузнец | 1234567890 |
3 | Майкл | Williams | 1357911131 |
SELECT * FROM Employees ORDER BY LName DESC
Или же
SELECT * FROM Employees ORDER BY LName ASC
Это заявление изменяет направление сортировки.
Можно также указать несколько столбцов сортировки. Например:
SELECT * FROM Employees ORDER BY LName ASC, FName ASC
Этот пример сначала сортирует результаты по LName
а затем для записей, имеющих одно и то же LName
, сортирует по FName
. Это даст вам результат, аналогичный тому, что вы найдете в телефонной книге.
Чтобы сохранить переименование имени столбца в предложении ORDER BY
, вместо него можно использовать номер столбца. Обратите внимание, что номера столбцов начинаются с 1.
SELECT Id, FName, LName, PhoneNumber FROM Employees ORDER BY 3
Вы также можете включить оператор CASE
в предложение ORDER BY
.
SELECT Id, FName, LName, PhoneNumber FROM Employees ORDER BY CASE WHEN LName='Jones` THEN 0 ELSE 1 END ASC
Это приведет к сортировке результатов, чтобы все записи были с LName
«Jones» вверху.
Выберите столбцы с именами из зарезервированных ключевых слов
Когда имя столбца соответствует зарезервированному ключевому слову, стандартный SQL требует, чтобы вы заключили его в двойные кавычки:
SELECT
"ORDER",
ID
FROM ORDERS
Обратите внимание, что это делает имя столбца чувствительным к регистру.
Некоторые СУБД имеют собственные способы цитирования имен. Например, для этой цели SQL Server использует квадратные скобки:
SELECT
[Order],
ID
FROM ORDERS
в то время как MySQL (и MariaDB) по умолчанию используют обратные ссылки:
SELECT
`Order`,
id
FROM orders
Выбор указанного количества записей
Стандарт SQL 2008 определяет предложение FETCH FIRST
, чтобы ограничить количество возвращенных записей.
SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
FETCH FIRST 10 ROWS ONLY
Этот стандарт поддерживается только в последних версиях некоторых RDMS. Специфический нестандартный синтаксис, предоставляемый поставщиком, предоставляется в других системах. Прогресс OpenEdge 11.x также поддерживает синтаксис FETCH FIRST <n> ROWS ONLY
.
Кроме того, OFFSET <m> ROWS
перед FETCH FIRST <n> ROWS ONLY
позволяет пропускать строки перед извлечением строк.
SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
OFFSET 5 ROWS
FETCH FIRST 10 ROWS ONLY
Следующий запрос поддерживается в SQL Server и MS Access:
SELECT TOP 10 Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
Чтобы сделать то же самое в MySQL или PostgreSQL, необходимо использовать ключевое слово LIMIT
:
SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
LIMIT 10
В Oracle то же самое можно сделать с ROWNUM
:
SELECT Id, ProductName, UnitPrice, Package
FROM Product
WHERE ROWNUM <= 10
ORDER BY UnitPrice DESC
Результаты : 10 записей.
Id ProductName UnitPrice Package
38 Côte de Blaye 263.50 12 - 75 cl bottles
29 Thüringer Rostbratwurst 123.79 50 bags x 30 sausgs.
9 Mishi Kobe Niku 97.00 18 - 500 g pkgs.
20 Sir Rodney's Marmalade 81.00 30 gift boxes
18 Carnarvon Tigers 62.50 16 kg pkg.
59 Raclette Courdavault 55.00 5 kg pkg.
51 Manjimup Dried Apples 53.00 50 - 300 g pkgs.
62 Tarte au sucre 49.30 48 pies
43 Ipoh Coffee 46.00 16 - 500 g tins
28 Rössle Sauerkraut 45.60 25 - 825 g cans
Нюансы поставщика:
Важно отметить, что TOP
в Microsoft SQL работает после WHERE
и возвращает указанное количество результатов, если они существуют в любой точке таблицы, в то время как ROWNUM
работает как часть WHERE
, поэтому, если другие условия не существуют в указанное количество строк в начале таблицы, вы получите нулевые результаты, когда могут быть найдены другие.
Выбор с псевдонимом таблицы
SELECT e.Fname, e.LName
FROM Employees e
Таблице Employees присваивается псевдоним «e» непосредственно после имени таблицы. Это помогает устранить неоднозначность в сценариях, где несколько таблиц имеют одинаковое имя поля, и вам нужно указать, в какой таблице вы хотите вернуть данные.
SELECT e.Fname, e.LName, m.Fname AS ManagerFirstName
FROM Employees e
JOIN Managers m ON e.ManagerId = m.Id
Обратите внимание, что как только вы определяете псевдоним, вы больше не можете использовать имя канонической таблицы. т.е.
SELECT e.Fname, Employees.LName, m.Fname AS ManagerFirstName
FROM Employees e
JOIN Managers m ON e.ManagerId = m.Id
будет выдавать ошибку.
Стоит отметить табличные псевдонимы - более формально «переменные диапазона» - были введены в язык SQL для решения проблемы дублированных столбцов, вызванных INNER JOIN
. Стандарт SQL 1992 года исправил этот ранее недостаток дизайна, введя NATURAL JOIN
(реализованный в mySQL, PostgreSQL и Oracle, но еще не в SQL Server), результат которого никогда не имеет повторяющихся имен столбцов. Вышеприведенный пример интересен тем, что таблицы объединяются в столбцы с разными именами ( Id
и ManagerId
), но не должны соединяться в столбцах с тем же именем ( LName
, FName
), требуя переименования столбцов, которые должны быть выполнены перед присоединением:
SELECT Fname, LName, ManagerFirstName
FROM Employees
NATURAL JOIN
( SELECT Id AS ManagerId, Fname AS ManagerFirstName
FROM Managers ) m;
Обратите внимание, что хотя переменная alias / range должна быть объявлена для таблицы dervied (иначе SQL будет выдавать ошибку), никогда не имеет смысла фактически использовать ее в запросе.
Выбор строк из нескольких таблиц
SELECT *
FROM
table1,
table2
SELECT
table1.column1,
table1.column2,
table2.column1
FROM
table1,
table2
Это называется кросс-продуктом в SQL, оно аналогично перекрестному продукту в наборах
Эти операторы возвращают выбранные столбцы из нескольких таблиц в одном запросе.
Между столбцами, возвращаемыми из каждой таблицы, нет никакой конкретной связи.
Выбор с помощью функций агрегации
Средний
Функция агрегацииAVG()
вернет среднее значение выбранных значений. SELECT AVG(Salary) FROM Employees
Совокупные функции также могут быть объединены с предложением where. SELECT AVG(Salary) FROM Employees where DepartmentId = 1
Совокупные функции также могут быть объединены с предложением group by. Если сотрудник разделен на несколько отделов, и мы хотим найти среднюю зарплату для каждого отдела, мы можем использовать следующий запрос.
SELECT AVG(Salary) FROM Employees GROUP BY DepartmentId
минимальный
Функция агрегатаMIN()
возвращает минимальное количество выбранных значений. SELECT MIN(Salary) FROM Employees
максимальная
Функция агрегацииMAX()
возвращает максимум выбранных значений. SELECT MAX(Salary) FROM Employees
подсчитывать
Функция агрегацииCOUNT()
возвращает количество выбранных значений. SELECT Count(*) FROM Employees
Его также можно комбинировать с условиями, чтобы получить количество строк, удовлетворяющих определенным условиям. SELECT Count(*) FROM Employees where ManagerId IS NOT NULL
Конкретные столбцы также могут быть указаны для получения количества значений в столбце. Обратите внимание, что значения NULL
не учитываются. Select Count(ManagerId) from Employees
Граф также может быть объединен с отдельным ключевым словом для отдельного счета. Select Count(DISTINCT DepartmentId) from Employees
сумма
Функция агрегатаSUM()
возвращает сумму значений, выбранных для всех строк. SELECT SUM(Salary) FROM Employees
Выбор с нулевым
SELECT Name FROM Customers WHERE PhoneNumber IS NULL
Выбор с нулями принимает другой синтаксис. Не используйте =
, используйте IS NULL
или IS NOT NULL
.
Выбор с помощью CASE
Когда результаты должны иметь некоторую логику, применяемую «на лету», можно использовать оператор CASE для ее реализации.
SELECT CASE WHEN Col1 < 50 THEN 'under' ELSE 'over' END threshold
FROM TableName
также может быть прикован
SELECT
CASE WHEN Col1 < 50 THEN 'under'
WHEN Col1 > 50 AND Col1 <100 THEN 'between'
ELSE 'over'
END threshold
FROM TableName
один может также иметь CASE
внутри другого оператора CASE
SELECT
CASE WHEN Col1 < 50 THEN 'under'
ELSE
CASE WHEN Col1 > 50 AND Col1 <100 THEN Col1
ELSE 'over' END
END threshold
FROM TableName
Выбор без блокировки таблицы
Иногда, когда таблицы используются в основном (или только) для чтения, индексирование больше не помогает, и каждый бит подсчитывается, можно использовать select без LOCK для повышения производительности.
SQL Server
SELECT * FROM TableName WITH (nolock)
MySQL
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM TableName;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
оракул
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM TableName;
DB2
SELECT * FROM TableName WITH UR;
где UR
означает «незафиксированное чтение».
Если вы используете таблицу, которая имеет изменения в записи, может иметь непредсказуемые результаты.
Выберите отдельные (только уникальные значения)
SELECT DISTINCT ContinentCode
FROM Countries;
Этот запрос вернет все значения DISTINCT
(уникальные, разные) из столбца ContinentCode
из таблицы Countries
ContinentCode |
---|
OC |
Евросоюз |
КАК |
Не Доступно |
AF |
Выбрать с условием нескольких значений из столбца
SELECT * FROM Cars WHERE status IN ( 'Waiting', 'Working' )
Это семантически эквивалентно
SELECT * FROM Cars WHERE ( status = 'Waiting' OR status = 'Working' )
т.е. value IN ( <value list> )
является сокращением для дизъюнкции (логическое OR
).
Получить агрегированный результат для групп строк
Подсчет строк на основе определенного значения столбца:
SELECT category, COUNT(*) AS item_count
FROM item
GROUP BY category;
Получение среднего дохода по отделу:
SELECT department, AVG(income)
FROM employees
GROUP BY department;
Важно выбрать только столбцы, указанные в предложении GROUP BY
или используемые с агрегатными функциями .
Предложение WHERE
также может использоваться с GROUP BY
, но WHERE
фильтрует записи до того, как будет выполнена какая-либо группировка:
SELECT department, AVG(income)
FROM employees
WHERE department <> 'ACCOUNTING'
GROUP BY department;
Если вам нужно отфильтровать результаты после завершения группировки, например, чтобы увидеть только отделы, средний доход которых превышает 1000, вам нужно использовать предложение HAVING
:
SELECT department, AVG(income)
FROM employees
WHERE department <> 'ACCOUNTING'
GROUP BY department
HAVING avg(income) > 1000;
Выбор с более чем 1 условием.
AND
ключевое слово используется для добавления дополнительных условий для запроса.
название | Возраст | Пол |
---|---|---|
Сэм | 18 | M |
Джон | 21 | M |
боб | 22 | M |
Мэри | 23 | F |
SELECT name FROM persons WHERE gender = 'M' AND age > 20;
Это вернет:
название |
---|
Джон |
боб |
использование ключевого слова OR
SELECT name FROM persons WHERE gender = 'M' OR age < 20;
Это вернет:
название |
---|
Сэм |
Джон |
боб |
Эти ключевые слова могут быть объединены для более сложных сочетаний критериев:
SELECT name
FROM persons
WHERE (gender = 'M' AND age < 20)
OR (gender = 'F' AND age > 20);
Это вернет:
название |
---|
Сэм |
Мэри |