# Série d'exercices SQL progressifs - Base AdventureWorks
## 🔹 Niveau 1 - Bases de la sélection (SELECT, WHERE, ORDER BY, LIMIT)
### Structure des tables principales utilisées :
- **[Link]** : Informations personnelles (FirstName, LastName, etc.)
- **[Link]** : Données clients
- **[Link]** : En-têtes des commandes
- **[Link]** : Catalogue produits
- **[Link]** : Stock des produits
### Exercices :
1. **Sélectionner toutes les colonnes de la table [Link]**
```sql
-- Table : [Link]
SELECT * FROM [Link];
```
2. **Afficher FirstName et LastName de toutes les personnes**
```sql
-- Table : [Link]
SELECT FirstName, LastName FROM [Link];
```
3. **Sélectionner les commandes passées après le 1er janvier 2014**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE OrderDate > '2014-01-01';
```
4. **Lister les produits dont le ListPrice est supérieur à 100$**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE ListPrice > 100;
```
5. **Trier les personnes par ordre alphabétique du LastName**
```sql
-- Table : [Link]
SELECT * FROM [Link]
ORDER BY LastName;
```
6. **Lister les 5 produits les plus chers**
```sql
-- Table : [Link]
SELECT TOP 5 * FROM [Link]
ORDER BY ListPrice DESC;
```
7. **Afficher les commandes dont le Status est 1 (en cours) ou 5 (livrée)**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE Status IN (1, 5);
```
8. **Sélectionner les personnes habitant dans la ville de Seattle**
```sql
-- Tables : [Link], [Link], [Link]
SELECT p.* FROM [Link] p
JOIN [Link] bea ON [Link] = [Link]
JOIN [Link] a ON [Link] = [Link]
WHERE [Link] = 'Seattle';
```
9. **Lister les produits avec une quantité en stock comprise entre 10 et 100**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE Quantity BETWEEN 10 AND 100;
```
10. **Afficher les personnes dont le LastName commence par "D"**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE LastName LIKE 'D%';
```
## 🔹 Niveau 2 - Fonctions, filtres avancés et chaînes de caractères
### Exercices :
1. **Afficher les noms en majuscules de toutes les personnes**
```sql
-- Table : [Link]
SELECT UPPER(LastName) AS NomMajuscule FROM [Link];
```
2. **Afficher le nombre total de caractères du champ Name de chaque produit**
```sql
-- Table : [Link]
SELECT Name, LEN(Name) AS NombreCaracteres FROM [Link];
```
3. **Extraire les 5 premiers caractères du ProductNumber des produits**
```sql
-- Table : [Link]
SELECT ProductNumber, LEFT(ProductNumber, 5) AS CodeCourt FROM [Link];
```
4. **Lister les produits dont le nom contient "Bike" (insensible à la casse)**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE UPPER(Name) LIKE '%BIKE%';
```
5. **Remplacer les tirets par des espaces dans les noms des produits**
```sql
-- Table : [Link]
SELECT Name, REPLACE(Name, '-', ' ') AS NomModifie FROM [Link];
```
6. **Afficher les personnes dont le FirstName contient exactement 5 lettres**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE LEN(FirstName) = 5;
```
7. **Supprimer les espaces avant et après les noms des produits**
```sql
-- Table : [Link]
SELECT Name, LTRIM(RTRIM(Name)) AS NomNettoye FROM [Link];
```
8. **Calculer le prix TTC (TVA 20%) pour chaque produit**
```sql
-- Table : [Link]
SELECT Name, ListPrice, ListPrice * 1.20 AS PrixTTC FROM [Link];
```
9. **Arrondir le ListPrice à 2 décimales**
```sql
-- Table : [Link]
SELECT Name, ROUND(ListPrice, 2) AS PrixArrondi FROM [Link];
```
10. **Ajouter un alias "VilleClient" pour la colonne City**
```sql
-- Tables : [Link]
SELECT City AS VilleClient FROM [Link];
```
## 🔹 Niveau 3 - Fonctions d'agrégation et GROUP BY
### Exercices :
1. **Compter le nombre total de personnes**
```sql
-- Table : [Link]
SELECT COUNT(*) AS NombrePersonnes FROM [Link];
```
2. **Calculer le montant total des commandes**
```sql
-- Table : [Link]
SELECT SUM(TotalDue) AS MontantTotal FROM [Link];
```
3. **Afficher le prix moyen des produits**
```sql
-- Table : [Link]
SELECT AVG(ListPrice) AS PrixMoyen FROM [Link];
```
4. **Lister le nombre de commandes par client**
```sql
-- Table : [Link]
SELECT CustomerID, COUNT(*) AS NombreCommandes
FROM [Link]
GROUP BY CustomerID;
```
5. **Afficher le total des ventes par produit**
```sql
-- Tables : [Link]
SELECT ProductID, SUM(LineTotal) AS TotalVentes
FROM [Link]
GROUP BY ProductID;
```
6. **Compter combien de produits ont un ListPrice > 50$**
```sql
-- Table : [Link]
SELECT COUNT(*) AS ProduitsChers
FROM [Link]
WHERE ListPrice > 50;
```
7. **Trouver le produit le plus cher**
```sql
-- Table : [Link]
SELECT TOP 1 * FROM [Link]
ORDER BY ListPrice DESC;
```
8. **Afficher le nombre de personnes par ville**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], COUNT(*) AS NombrePersonnes
FROM [Link] p
JOIN [Link] bea ON [Link] = [Link]
JOIN [Link] a ON [Link] = [Link]
GROUP BY [Link];
```
9. **Calculer le chiffre d'affaires mensuel**
```sql
-- Table : [Link]
SELECT YEAR(OrderDate) AS Annee, MONTH(OrderDate) AS Mois,
SUM(TotalDue) AS ChiffreAffaires
FROM [Link]
GROUP BY YEAR(OrderDate), MONTH(OrderDate)
ORDER BY Annee, Mois;
```
10. **Lister les produits avec une moyenne de ventes supérieure à 500$**
```sql
-- Table : [Link]
SELECT ProductID, AVG(LineTotal) AS MoyenneVentes
FROM [Link]
GROUP BY ProductID
HAVING AVG(LineTotal) > 500;
```
## 🔹 Niveau 4 - Jointures (INNER, LEFT, RIGHT, FULL)
### Exercices :
1. **Lister les commandes avec le nom du client (INNER JOIN)**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link], [Link], [Link]
FROM [Link] soh
INNER JOIN [Link] c ON [Link] = [Link]
INNER JOIN [Link] p ON [Link] = [Link];
```
2. **Afficher tous les clients avec leurs commandes, même s'ils n'en ont pas (LEFT JOIN)**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link], [Link], [Link]
FROM [Link] c
LEFT JOIN [Link] soh ON [Link] = [Link]
LEFT JOIN [Link] p ON [Link] = [Link];
```
3. **Lister tous les produits et leurs commandes (même s'ils ne sont pas commandés)**
```sql
-- Tables : [Link], [Link]
SELECT [Link], [Link], [Link]
FROM [Link] p
LEFT JOIN [Link] sod ON [Link] = [Link];
```
4. **Récupérer les commandes avec les détails du produit et du client**
```sql
-- Tables : [Link], [Link], [Link], [Link],
[Link]
SELECT [Link], [Link], [Link],
[Link], [Link], [Link]
FROM [Link] soh
JOIN [Link] sod ON [Link] = [Link]
JOIN [Link] prod ON [Link] = [Link]
JOIN [Link] c ON [Link] = [Link]
JOIN [Link] per ON [Link] = [Link];
```
5. **Trouver les clients sans commande (LEFT JOIN + IS NULL)**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link]
FROM [Link] c
LEFT JOIN [Link] soh ON [Link] = [Link]
LEFT JOIN [Link] p ON [Link] = [Link]
WHERE [Link] IS NULL;
```
6. **Trouver les produits jamais commandés**
```sql
-- Tables : [Link], [Link]
SELECT [Link], [Link]
FROM [Link] p
LEFT JOIN [Link] sod ON [Link] = [Link]
WHERE [Link] IS NULL;
```
7. **Créer une jointure entre commandes et détails de commande**
```sql
-- Tables : [Link], [Link]
SELECT [Link], [Link], [Link], [Link]
FROM [Link] soh
JOIN [Link] sod ON [Link] = [Link];
```
8. **Afficher le nombre de commandes par client avec leur nom**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link], COUNT([Link]) AS NombreCommandes
FROM [Link] c
LEFT JOIN [Link] soh ON [Link] = [Link]
LEFT JOIN [Link] p ON [Link] = [Link]
GROUP BY [Link], [Link];
```
9. **Lister les produits et le nom du client qui les a le plus commandés**
```sql
-- Tables : [Link], [Link], [Link], [Link],
[Link]
SELECT [Link], [Link], [Link], SUM([Link]) AS QuantiteTotale
FROM [Link] prod
JOIN [Link] sod ON [Link] = [Link]
JOIN [Link] soh ON [Link] = [Link]
JOIN [Link] c ON [Link] = [Link]
JOIN [Link] per ON [Link] = [Link]
GROUP BY [Link], [Link], [Link]
ORDER BY QuantiteTotale DESC;
```
10. **Trouver les clients ayant commandé plus d'une fois le même produit**
```sql
-- Tables : [Link], [Link], [Link], [Link]
SELECT [Link], [Link], [Link], COUNT(*) AS NombreCommandes
FROM [Link] soh
JOIN [Link] sod ON [Link] = [Link]
JOIN [Link] prod ON [Link] = [Link]
JOIN [Link] c ON [Link] = [Link]
JOIN [Link] p ON [Link] = [Link]
GROUP BY [Link], [Link], [Link]
HAVING COUNT(*) > 1;
```
## 🔹 Niveau 5 - Sous-requêtes et CTE (WITH)
### Exercices :
1. **Trouver les clients qui ont dépensé plus que la moyenne des clients**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link], SUM([Link]) AS TotalDepenses
FROM [Link] c
JOIN [Link] soh ON [Link] = [Link]
JOIN [Link] p ON [Link] = [Link]
GROUP BY [Link], [Link]
HAVING SUM([Link]) > (
SELECT AVG(TotalClient)
FROM (SELECT SUM(TotalDue) AS TotalClient
FROM [Link]
GROUP BY CustomerID) AS MoyenneClients
);
```
2. **Afficher les produits dont le prix est supérieur au prix moyen**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE ListPrice > (SELECT AVG(ListPrice) FROM [Link]);
```
3. **Trouver les clients dont le nombre de commandes est supérieur à 5**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link], COUNT([Link]) AS NombreCommandes
FROM [Link] c
JOIN [Link] soh ON [Link] = [Link]
JOIN [Link] p ON [Link] = [Link]
GROUP BY [Link], [Link]
HAVING COUNT([Link]) > 5;
```
4. **Utiliser une CTE pour afficher les clients et leur total de commandes**
```sql
-- Tables : [Link], [Link], [Link]
WITH ClientCommandes AS (
SELECT [Link], [Link], [Link],
COUNT([Link]) AS NombreCommandes,
SUM([Link]) AS TotalDepenses
FROM [Link] c
LEFT JOIN [Link] soh ON [Link] = [Link]
LEFT JOIN [Link] p ON [Link] = [Link]
GROUP BY [Link], [Link], [Link]
)
SELECT * FROM ClientCommandes;
```
5. **Utiliser une sous-requête pour trouver le top 5 des produits les plus commandés**
```sql
-- Tables : [Link], [Link]
SELECT TOP 5 [Link], SUM([Link]) AS QuantiteTotale
FROM [Link] p
JOIN [Link] sod ON [Link] = [Link]
GROUP BY [Link]
ORDER BY QuantiteTotale DESC;
```
6. **Lister les clients dont le total de commandes est supérieur à tous les autres clients**
```sql
-- Tables : [Link], [Link], [Link]
SELECT [Link], [Link], SUM([Link]) AS TotalDepenses
FROM [Link] c
JOIN [Link] soh ON [Link] = [Link]
JOIN [Link] p ON [Link] = [Link]
GROUP BY [Link], [Link]
HAVING SUM([Link]) >= ALL (
SELECT SUM(TotalDue)
FROM [Link]
GROUP BY CustomerID
);
```
7. **Utiliser une CTE pour afficher les produits avec leur prix et leur catégorie**
```sql
-- Tables : [Link], [Link], [Link]
WITH ProduitsCategorie AS (
SELECT [Link], [Link],
[Link] AS Categorie,
[Link] AS SousCategorie
FROM [Link] p
LEFT JOIN [Link] psc ON [Link] =
[Link]
LEFT JOIN [Link] pc ON [Link] = [Link]
)
SELECT * FROM ProduitsCategorie;
```
8. **Trouver le deuxième produit le plus cher avec une sous-requête**
```sql
-- Table : [Link]
SELECT * FROM [Link]
WHERE ListPrice = (
SELECT MAX(ListPrice) FROM [Link]
WHERE ListPrice < (SELECT MAX(ListPrice) FROM [Link])
);
```
9. **Afficher les commandes où le montant est supérieur à la moyenne du mois**
```sql
-- Table : [Link]
SELECT [Link], [Link],