Примеры SELECT (Transact-SQL)
Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure
В этой статье приведены примеры использования инструкции SELECT .
Примеры кода Transact-SQL в этой статье используют AdventureWorks2022
базу данных или AdventureWorksDW2022
пример базы данных, которую можно скачать с домашней страницы примеров и проектов сообщества Microsoft SQL Server.
А. Использование SELECT для получения строк и столбцов
В следующем примере приведены три примера кода. В ходе выполнения первого примера кода возвращаются все строки (предложение WHERE не указано), а также все столбцы (используется звездочка, *
) таблицы Product
базы данных AdventureWorks2022
.
USE AdventureWorks2022;
GO
SELECT *
FROM Production.Product
ORDER BY Name ASC;
-- Alternate way.
USE AdventureWorks2022;
GO
SELECT p.*
FROM Production.Product AS p
ORDER BY Name ASC;
GO
В ходе выполнения данного примера кода происходит выдача всех строк (предложение WHERE не задано) и подмножества столбцов (Name
, ProductNumber
, ListPrice
) таблицы Product
базы данных AdventureWorks2022
. Дополнительно выведено название столбца.
USE AdventureWorks2022;
GO
SELECT Name,
ProductNumber,
ListPrice AS Price
FROM Production.Product
ORDER BY Name ASC;
GO
В ходе выполнения данного примера кода происходит выдача всех строк таблицы Product
, для которых линейки продуктов начинаются символом R
и для которых длительность изготовления не превышает 4
дней.
USE AdventureWorks2022;
GO
SELECT Name,
ProductNumber,
ListPrice AS Price
FROM Production.Product
WHERE ProductLine = 'R'
AND DaysToManufacture < 4
ORDER BY Name ASC;
GO
B. Использование SELECT с заголовками столбцов и вычислениями
В ходе выполнения следующего примера возвращаются все строки таблицы Product
. В результате выполнения первого примера выдаются все объемы продаж и скидки по всем продуктам. Во втором примере вычисляется годовой доход от продажи каждого вида продукции.
USE AdventureWorks2022;
GO
SELECT p.Name AS ProductName,
NonDiscountSales = (OrderQty * UnitPrice),
Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY ProductName DESC;
GO
Данный запрос вычисляет доход от продажи по каждому виду продукции для каждого заказа.
USE AdventureWorks2022;
GO
SELECT 'Total income is',
((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)),
' for ',
p.Name AS ProductName
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY ProductName ASC;
GO
C. Использование DISTINCT с SELECT
В приведенном ниже примере для предотвращения получения повторяющихся заголовков используется оператор DISTINCT
.
USE AdventureWorks2022;
GO
SELECT DISTINCT JobTitle
FROM HumanResources.Employee
ORDER BY JobTitle;
GO
D. Создание таблиц с помощью SELECT INTO
В следующем примере в базе данных #Bicycles
создается временная таблица tempdb
.
USE tempdb;
GO
IF OBJECT_ID(N'#Bicycles', N'U') IS NOT NULL
DROP TABLE #Bicycles;
GO
SELECT *
INTO #Bicycles
FROM AdventureWorks2022.Production.Product
WHERE ProductNumber LIKE 'BK%';
GO
В данном примере создается постоянная таблица NewProducts
.
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL
DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks2022 SET RECOVERY BULK_LOGGED;
GO
SELECT *
INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2022 SET RECOVERY FULL;
GO
Е. Использование сопоставленных вложенных запросов
Коррелированный запрос — это запрос, зависящий от результатов выполнения другого запроса. Этот запрос можно выполнять многократно, один раз для каждой строки, которая может быть выбрана внешним запросом.
В первом примере представлены семантически эквивалентные запросы для демонстрации различий в использовании ключевых слов EXISTS
и IN
. В обоих примерах приведены допустимые вложенные запросы, извлекающие по одному экземпляру продукции каждого наименования, для которых модель продукта — «long sleeve logo jersey» (кофта с длинными рукавами, с эмблемой), а значения столбцов ProductModelID
таблиц Product
и ProductModel
совпадают.
USE AdventureWorks2022;
GO
SELECT DISTINCT Name
FROM Production.Product AS p
WHERE EXISTS (
SELECT *
FROM Production.ProductModel AS pm
WHERE p.ProductModelID = pm.ProductModelID
AND pm.Name LIKE 'Long-Sleeve Logo Jersey%'
);
GO
-- OR
USE AdventureWorks2022;
GO
SELECT DISTINCT Name
FROM Production.Product
WHERE ProductModelID IN (
SELECT ProductModelID
FROM Production.ProductModel AS pm
WHERE p.ProductModelID = pm.ProductModelID
AND Name LIKE 'Long-Sleeve Logo Jersey%'
);
GO
В следующем примере используется и извлекается IN
один экземпляр первого имени и имени семьи каждого сотрудника, для которого указан 5000.00
бонус в SalesPerson
таблице, и для которого идентификаторы сотрудников совпадают в Employee
таблицах и SalesPerson
таблицах.
USE AdventureWorks2022;
GO
SELECT DISTINCT p.LastName,
p.FirstName
FROM Person.Person AS p
INNER JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = p.BusinessEntityID
WHERE 5000.00 IN (
SELECT Bonus
FROM Sales.SalesPerson AS sp
WHERE e.BusinessEntityID = sp.BusinessEntityID
);
GO
Предыдущий вложенный запрос в этом операторе нельзя оценивать независимо от внешнего запроса. Он требует значения параметра Employee.EmployeeID
, однако это значение меняется, когда ядро СУБД SQL Server обрабатывает строки в Employee
.
Коррелированный вложенный запрос также может использоваться в предложении HAVING
внешнего запроса. В данном примере осуществляется поиск моделей продуктов, для которых максимальная цена в каталоге в два раза превышает среднюю цену по нему.
USE AdventureWorks2022;
GO
SELECT p1.ProductModelID
FROM Production.Product AS p1
GROUP BY p1.ProductModelID
HAVING MAX(p1.ListPrice) >= (
SELECT AVG(p2.ListPrice) * 2
FROM Production.Product AS p2
WHERE p1.ProductModelID = p2.ProductModelID
);
GO
В этом примере используются два сопоставленных вложенных запроса для поиска имен сотрудников, которые продали определенный продукт.
USE AdventureWorks2022;
GO
SELECT DISTINCT pp.LastName,
pp.FirstName
FROM Person.Person pp
INNER JOIN HumanResources.Employee e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE pp.BusinessEntityID IN (
SELECT SalesPersonID
FROM Sales.SalesOrderHeader
WHERE SalesOrderID IN (
SELECT SalesOrderID
FROM Sales.SalesOrderDetail
WHERE ProductID IN (
SELECT ProductID
FROM Production.Product p
WHERE ProductNumber = 'BK-M68B-42'
)
)
);
GO
F. Использование GROUP BY
В следующем примере находится общий объем продаж для каждого заказа в базе данных.
USE AdventureWorks2022;
GO
SELECT SalesOrderID,
SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
ORDER BY SalesOrderID;
GO
Так как в запросе используется предложение GROUP BY
, то для каждого заказа выводится только одна строка, содержащая общий объем продаж.
G. Использование GROUP BY с несколькими группами
В данном примере вычисляются средние цены и объемы продаж за последний год, сгруппированные по коду продукта и идентификатору специального предложения.
USE AdventureWorks2022;
GO
SELECT ProductID,
SpecialOfferID,
AVG(UnitPrice) AS [Average Price],
SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY ProductID,
SpecialOfferID
ORDER BY ProductID;
GO
H. Использование GROUP BY и WHERE
В следующем примере после извлечения строк, содержащих цены каталога, превышающие $1000
, происходит их разделение на группы.
USE AdventureWorks2022;
GO
SELECT ProductModelID,
AVG(ListPrice) AS [Average List Price]
FROM Production.Product
WHERE ListPrice > $1000
GROUP BY ProductModelID
ORDER BY ProductModelID;
GO
I. Использование GROUP BY с выражением
В следующем примере производится группировка с помощью выражения. Можно сгруппировать по выражению, если выражение не включает агрегатные функции.
USE AdventureWorks2022;
GO
SELECT AVG(OrderQty) AS [Average Quantity],
NonDiscountSales = (OrderQty * UnitPrice)
FROM Sales.SalesOrderDetail
GROUP BY (OrderQty * UnitPrice)
ORDER BY (OrderQty * UnitPrice) DESC;
GO
J. Использование GROUP BY с ORDER BY
В следующем примере для каждого типа продуктов вычисляется средняя цена, а также осуществляется сортировка полученных результатов по возрастанию.
USE AdventureWorks2022;
GO
SELECT ProductID,
AVG(UnitPrice) AS [Average Price]
FROM Sales.SalesOrderDetail
WHERE OrderQty > 10
GROUP BY ProductID
ORDER BY AVG(UnitPrice);
GO
K. Использование предложения HAVING
В первом из приведенных ниже примеров показывается использование предложения HAVING
с агрегатной функцией. В нем производится группировка строк таблицы SalesOrderDetail
по коду продукта, а также удаляются строки, соответствующие продуктам, для которых средний объем заказа не превышает пяти. Во втором примере показывается использование предложения HAVING
без агрегатной функции.
USE AdventureWorks2022;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO
В данном запросе внутри предложения LIKE
используется предложение HAVING
.
USE AdventureWorks2022;
GO
SELECT SalesOrderID, CarrierTrackingNumber
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID, CarrierTrackingNumber
HAVING CarrierTrackingNumber LIKE '4BD%'
ORDER BY SalesOrderID ;
GO
L. Использование HAVING и GROUP BY
В следующем примере показано использование предложений GROUP BY
, HAVING
, WHERE
и ORDER BY
в одной инструкции SELECT
. В результате его выполнения в группах и сводных значениях не учитываются строки, соответствующие продуктам с ценами выше $25 и средним объемом заказов ниже 5. Также осуществляется сортировка результатов по ProductID
.
USE AdventureWorks2022;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
WHERE UnitPrice < 25.00
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO
M. Использование HAVING с СУММ и AVG
В следующем примере производится группировка строк таблицы SalesOrderDetail
по коду продукта, а затем выводятся только те группы, для которых общий объем продаж составляет более $1000000.00
, а средний объем заказа не превышает 3
.
USE AdventureWorks2022;
GO
SELECT ProductID,
AVG(OrderQty) AS AverageQuantity,
SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
AND AVG(OrderQty) < 3;
GO
Чтобы просмотреть продукты с общим объемом продаж, превышающих $2000000.00
, используйте следующий запрос:
USE AdventureWorks2022;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00;
GO
Если вы хотите убедиться в наличии не менее 1500 элементов, участвующих в вычислениях для каждого продукта, используйте HAVING COUNT(*) > 1500
для устранения продуктов, возвращающих итоги для меньшего количества 1500
проданных элементов. Этот запрос выглядит следующим образом.
USE AdventureWorks2022;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500;
GO
О. Использование указания оптимизатора INDEX
В следующем примере показаны два способа использования указания оптимизатора INDEX
. В первом примере показано, как принудительно принудить оптимизатора использовать некластеризованный индекс для получения строк из таблицы. Во втором примере выполняется проверка таблицы с помощью индекса 0.
USE AdventureWorks2022;
GO
SELECT pp.FirstName,
pp.LastName,
e.NationalIDNumber
FROM HumanResources.Employee AS e WITH (INDEX (AK_Employee_NationalIDNumber))
INNER JOIN Person.Person AS pp
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
-- Force a table scan by using INDEX = 0.
USE AdventureWorks2022;
GO
SELECT pp.LastName,
pp.FirstName,
e.JobTitle
FROM HumanResources.Employee AS e WITH (INDEX = 0)
INNER JOIN Person.Person AS pp
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
M. Использование OPTION и подсказок GROUP
В следующем примере демонстрируется совместное использование предложений OPTION (GROUP)
и GROUP BY
.
USE AdventureWorks2022;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO
O. Использование указания запроса UNION
В следующем примере используется указание запроса MERGE UNION
.
USE AdventureWorks2022;
GO
SELECT BusinessEntityID,
JobTitle,
HireDate,
VacationHours,
SickLeaveHours
FROM HumanResources.Employee AS e1
UNION
SELECT BusinessEntityID,
JobTitle,
HireDate,
VacationHours,
SickLeaveHours
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO
P. Использование UNION
При выполнении следующего примера в результирующий набор включается содержимое столбцов ProductModelID
и Name
таблиц ProductModel
и Gloves
.
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO
-- Here is the simple union.
USE AdventureWorks2022;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO
В. Использование SELECT INTO с UNION
При выполнении следующего примера предложение INTO
во второй инструкции SELECT
указывает, что в таблице с именем ProductResults
содержится итоговый результирующий набор объединения заданных столбцов таблиц ProductModel
и Gloves
. Таблица Gloves
была создана в результате выполнения первой инструкции SELECT
.
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.ProductResults', 'U') IS NOT NULL
DROP TABLE dbo.ProductResults;
GO
IF OBJECT_ID('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO
USE AdventureWorks2022;
GO
SELECT ProductModelID, Name
INTO dbo.ProductResults
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO
SELECT ProductModelID, Name
FROM dbo.ProductResults;
R. Использование UNION двух операторов SELECT с ORDER BY
При использовании предложения UNION необходимо соблюдать порядок следования определенных параметров. В следующем примере показаны случаи правильного и неверного использования UNION
в двух инструкциях SELECT
, в которых необходимо переименовать столбцы на выходе.
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO
/* INCORRECT */
USE AdventureWorks2022;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
ORDER BY Name
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO
/* CORRECT */
USE AdventureWorks2022;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO
S. Использование UNION трех инструкций SELECT для отображения эффектов ALL и круглых скобок
В следующих примерах используются UNION
для объединения результатов трех таблиц, которые имеют одинаковые пять строк данных. В первом примере используется предложение UNION ALL
, в результате чего выдаются все 15 строк. Второй пример используется без ALL
исключения повторяющихся UNION
строк из объединенных результатов трех SELECT
операторов и возвращает пять строк.
В третьем примере с первым предложением ALL
используется ключевое слово UNION
, а во втором предложении UNION
вместо ключевого слова ALL
используются скобки. Второй UNION
обрабатывается сначала, так как он находится в скобках, и возвращает пять строк, так как ALL
параметр не используется и дубликаты удаляются. Эти пять строк объединяются с результатами первого SELECT
с помощью UNION ALL
ключевых слов. В данном случае повторяющиеся строки двух множеств, состоящих из пяти строк, не удаляются. Окончательный результат состоит из 10 строк.
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.EmployeeOne', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeOne;
GO
IF OBJECT_ID('dbo.EmployeeTwo', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeTwo;
GO
IF OBJECT_ID('dbo.EmployeeThree', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeThree;
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
INTO dbo.EmployeeOne
FROM Person.Person AS pp
INNER JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
INTO dbo.EmployeeTwo
FROM Person.Person AS pp
INNER JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
INTO dbo.EmployeeThree
FROM Person.Person AS pp
INNER JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
-- Union ALL
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeOne
UNION ALL
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeTwo
UNION ALL
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeThree;
GO
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeOne
UNION
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeThree;
GO
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeOne
UNION ALL
(
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeThree
);
GO
Связанный контент
- CREATE TRIGGER (Transact-SQL)
- CREATE VIEW (Transact-SQL)
- DELETE (Transact-SQL)
- EXECUTE (Transact-SQL)
- Выражения (Transact-SQL)
- INSERT (Transact-SQL)
- LIKE (Transact-SQL)
- Операторы set — UNION (Transact-SQL)
- Операторы set — EXCEPT и INTERSECT (Transact-SQL)
- UPDATE (Transact-SQL)
- WHERE (Transact-SQL)
- PathName (Transact-SQL)
- SELECT — предложение INTO (Transact-SQL)