Exemples SELECT (Transact-SQL)

S’applique à :SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Cet article fournit des exemples d'utilisation de l'instruction SELECT.

Cet article requiert l'exemple de bases de données AdventureWorks2022, que vous pouvez télécharger à partir de la page d'accueil des exemples et projets de communautés Microsoft SQL Server.

A. Utilisation de SELECT pour récupérer des lignes et des colonnes

L'exemple suivant présente trois exemples de code. Le premier exemple de code retourne toutes les lignes (aucune clause WHERE n'est définie) et toutes les colonnes (en utilisant *) de la table Product dans la base de données 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

Cet exemple retourne toutes les lignes (aucune clause WHERE n'est définie) et uniquement un sous-ensemble des colonnes (Name, ProductNumber, ListPrice) de la table Product dans la base de données AdventureWorks2022. En outre, un en-tête de colonne est ajouté.

USE AdventureWorks2022;
GO

SELECT Name,
    ProductNumber,
    ListPrice AS Price
FROM Production.Product
ORDER BY Name ASC;
GO

Cet exemple retourne uniquement les lignes de Product dont la ligne de produits a pour valeur R et dont le nombre de jours nécessaires à la fabrication est inférieur à 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. Utilisation de SELECT pour les en-têtes de colonnes et les calculs

Les exemples suivants retournent toutes les lignes de la table Product. Le premier exemple retourne le total des ventes et les remises pour chaque produit. Dans le second exemple, le gain est calculé pour chaque produit.

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

Voici la requête qui calcule le gain pour chaque produit dans chaque commande.

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. Utilisation de DISTINCT avec SELECT

L'exemple suivant utilise DISTINCT afin d'éviter l'extraction de titres en double.

USE AdventureWorks2022;
GO

SELECT DISTINCT JobTitle
FROM HumanResources.Employee
ORDER BY JobTitle;
GO

D. Création de tables avec SELECT INTO

Le premier exemple suivant crée une table temporaire nommée #Bicycles dans 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

Ce second exemple crée la table permanente 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

E. Utilisation de sous-requêtes corrélées

Une sous-requête corrélée est une requête dont les valeurs dépendent de la requête externe. Cette requête peut être exécutée de manière répétée, une fois pour chaque ligne susceptible d'être sélectionnée par la requête externe.

Le premier exemple montre des requêtes sémantiquement équivalentes pour illustrer la différence entre l’utilisation du mot clé EXISTS et celle du mot clé IN. Les deux exemples illustrent une sous-requête valide qui extrait une instance de chaque nom de produit dont le modèle est un pull-over à manches longues (« long sleeve logo jersey »), et dont le numéro ProductModelID se trouve dans les tables Product et 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

L’exemple suivant utilise IN et récupère une instance du prénom et du nom de famille de chaque employé pour lequel la prime dans la table SalesPerson est 5000.00, et pour lequel les numéros d'identification de l'employé correspondent dans les tables Employee et 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

La sous-requête précédente de cette instruction ne peut pas être évaluée indépendamment de la requête externe. Elle requiert en effet une valeur pour Employee.EmployeeID, mais cette valeur change à mesure que le moteur de base de données SQL Server examine les différentes lignes de la table Employee.

Une sous-requête en corrélation peut également s'employer dans la clause HAVING d'une requête externe. Cet exemple recherche les modèles de produit dont le tarif maximum est supérieur au double du tarif moyen du modèle concerné.

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

Cet exemple utilise deux sous-requêtes corrélées pour trouver les noms des employés qui ont vendu un produit spécifique.

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. Utilisation de GROUP BY

L'exemple suivant calcule le total de chaque commande dans la base de données.

USE AdventureWorks2022;
GO

SELECT SalesOrderID,
    SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
ORDER BY SalesOrderID;
GO

Du fait de la clause GROUP BY, une seule ligne est retournée pour chaque commande et elle contient la somme de toutes les ventes de cette dernière.

G. Utilisation de GROUP BY avec plusieurs groupes

L'exemple suivant affiche le prix moyen et la somme des ventes annuelles cumulées, regroupés par ID de produit et ID d'offre spéciale :

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. Utilisation de GROUP BY et WHERE

L'exemple suivant présente les résultats en groupes après n'avoir extrait que les lignes avec des tarifs supérieurs à $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. Utilisation de GROUP BY avec une expression

L'exemple suivant effectue un regroupement en fonction d'une expression. Vous pouvez spécifier un regroupement en fonction d'une expression à condition qu'elle ne contienne pas de fonction d'agrégation.

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. Utilisation de GROUP BY avec ORDER BY

L'exemple suivant calcule le prix moyen de chaque type de produit et trie les résultats en conséquence :

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. Utiliasation de la clause HAVING

Le premier exemple suivant illustre une clause HAVING utilisée avec une fonction d'agrégation. Il regroupe les lignes de la table SalesOrderDetail par ID de produit et élimine les produits dont la quantité moyenne d’articles commandés est inférieure ou égale à cinq. Le second exemple illustre une clause HAVING sans fonction d'agrégation.

USE AdventureWorks2022;
GO

SELECT ProductID
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

La requête suivante utilise la clause LIKE dans la clause HAVING.

USE AdventureWorks2022;
GO
SELECT SalesOrderID, CarrierTrackingNumber
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID, CarrierTrackingNumber
HAVING CarrierTrackingNumber LIKE '4BD%'
ORDER BY SalesOrderID ;
GO

L. Utilisation de HAVING et de GROUP BY

L'exemple suivant illustre l'utilisation des clauses GROUP BY, HAVING, WHERE et ORDER BY dans une instruction SELECT. Il génère des groupes et des valeurs résumées mais uniquement après avoir éliminé les produits dont le prix est supérieur à 25 $ et dont la quantité moyenne commandée est inférieure à 5. Il trie également les résultats par 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. Utilisation de HAVING avec SUM et AVG

L'exemple suivant regroupe la table SalesOrderDetail par ID de produit et ne comprend que les groupes de produits dont les commandes s'élèvent à plus de $1000000.00 et dont la quantité moyenne d'articles achetés est inférieure à 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

Pour visualiser les produits dont le total des ventes est supérieur à $2000000.00, utilisez la requête suivante :

USE AdventureWorks2022;
GO

SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00;
GO

Si vous souhaitez vous assurer qu'il y a au moins 1 500 articles impliqués dans les calculs pour chaque produit, utilisez HAVING COUNT(*) > 1500 pour éliminer les produits qui renvoient des totaux inférieurs aux 1500 articles vendus. La requête ressemble à ceci :

USE AdventureWorks2022;
GO

SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500;
GO

N. Utilisation du conseil de l'optimiseur d'INDEX

L'exemple suivant illustre deux manières d'utiliser l'indicateur d'optimiseur INDEX. Le premier exemple montre comment forcer l'optimiseur à utiliser un index non groupé pour récupérer les lignes d'une table. Le deuxième exemple force une analyse de table à l’aide d’un index de 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. Utilisation de l'OPTION et des conseils GROUP

L'exemple suivant montre comment la clause OPTION (GROUP) est utilisée avec une clause 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. Utilisation du conseil de requête UNION

L'exemple suivant utilise l'indicateur de requête 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. Utilisation d'une UNION

Dans l'exemple suivant, le jeu de résultats comprend le contenu des colonnes ProductModelID et Name des deux tables ProductModel et 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

Q : Utilisation de SELECT INTO avec UNION

Dans l'exemple suivant, la clause INTO de la seconde instruction SELECT indique que la table nommée ProductResults contient le jeu de résultats final de l'union des colonnes désignées des tables ProductModel et Gloves. La table Gloves est créée dans la première instruction 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. Utilisation de l'UNION de deux instructions SELECT avec ORDER BY

L'ordre de certains paramètres utilisés avec la clause UNION est important. L'exemple suivant illustre l'utilisation incorrecte et correcte de UNION dans deux instructions SELECT où une colonne doit être renommée dans le résultat.

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. Utilisation de l'UNION de trois instructions SELECT pour montrer les effets de ALL et des parenthèses

Les exemples suivants utilisent UNION pour combiner les résultats de trois tableaux contenant les mêmes cinq lignes de données. Le premier exemple utilise UNION ALL pour montrer les doublons d'enregistrement et retourne l'ensemble des 15 lignes. Le deuxième exemple utilise UNION sans ALL pour éliminer es lignes dupliquées des résultats combinés des trois instructions SELECT et retourne cinque lignes.

Le troisième exemple utilise ALL avec la première clause UNION et met entre parenthèses la seconde clause UNION qui n'utilise pas ALL. La seconde UNION est traitée en premier parce qu'elle est entre parenthèses, et renvoie cinq lignes parce que l'option ALL n'est pas utilisée et que les doublons sont supprimés. Ces cinq lignes sont combinées avec les résultats de la première SELECT en utilisant les mots-clés UNION ALL. Cet exemple ne supprime pas les doublons entre les deux ensembles de cinq lignes. Le résultat final contient 10 lignes.

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