Поиск…


Вступление

Оператор 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 ЭТО

Предупреждения против использования

Как правило, рекомендуется использовать * в производственном коде, где это возможно, поскольку это может вызвать ряд потенциальных проблем, в том числе:

  1. Избыток ввода-вывода, загрузка сети, использование памяти и т. Д. Из-за того, что данные базы данных не считывают данные и не передают их интерфейсу. Это особенно опасно, когда могут быть большие поля, такие как те, которые используются для хранения длинных заметок или прикрепленных файлов.
  2. Дальнейшая избыточная загрузка ввода-вывода, если базе данных необходимо спутать внутренние результаты на диск как часть обработки запроса более сложным, чем SELECT <columns> FROM <table> .
  3. Дополнительная обработка (и / или даже больше ввода-вывода), если некоторые из ненужных столбцов:
    • вычисляемые столбцы в базах данных, которые их поддерживают
    • в случае выбора из представления столбцы из таблицы / представления, которые оптимизатор запросов мог бы в противном случае оптимизировать
  4. Потенциал неожиданных ошибок, если столбцы добавляются к таблицам и представлениям позже, приводит к неоднозначным именам столбцов. Например, 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

Демоверсия SQLFiddle

Выбрать с условием нескольких значений из столбца

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);

Это вернет:

название
Сэм
Мэри


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow