Dans cette section, vous trouverez des ressources sur les cours que j'enseigne à savoir de la documentation, du code, des vidéos etc. Dès que je trouve quelque chose d'intéressant à partager, je le mettrai à disposition ici pour mes étudiants.
Travaux dirigés 16
##Auteur : Enseignant ##École : Collège Marie Victorin ##Session : Hiver 2026 ##Titre du cours : Introduction aux bases de données ##Titre du programme : Travaux dirigés 16 ##Version : 1.0 ##Date : 00/00/2026 ##Langage et version : SQL ##Moteur : SQL Server Express
-- ============================================================================== -- Les commandes DML : Les sous requêtes -- Les sous requetes -- Objectif : -- Ce Laboratoire vise à acquérir les compétences suivantes -- ======================================================== -- Les regroupements, les conditions multicritères, les jointures -- Les sous requetes. -- Base de données à utiliser : AdventureWorksEvalFR USE AdventureWorksEvalFR; GO
-- Requête 1 -- ********* -- Afficher les motifs de vente dont le type est connu et dont le nom contient le mot Price ou le mot Promotion. -- On affichera : -- l’identifiant du motif -- le nom du motif -- le type du motif -- Trier les résultats par type de motif, puis par nom. -- Vote code ici SELECT IDMotifVente, Nom, TypeMotif FROM dbo.MotifVente WHERE TypeMotif IS NOT NULL AND ( Nom LIKE '%Price%' OR Nom LIKE '%Promotion%' ) ORDER BY TypeMotif, Nom;
-- Requête 2
-- *********
-- Afficher les personnes dont le type de personne est un des types utilisés par au moins 500 personnes.
-- On affichera :
-- l’identifiant de la personne ;
-- le type de personne ;
-- le prénom ;
-- le nom de famille ;
-- la promotion courriel.
-- Afficher uniquement les personnes dont le prénom et le nom de famille sont connus.
-- Trier le résultat type de personne et par nom de famille
-- Vote code ici
SELECT
IDEntiteAffaires,
TypePersonne,
Prenom,
NomFamille,
PromotionCourriel
FROM dbo.Personne
WHERE Prenom IS NOT NULL
AND NomFamille IS NOT NULL
AND TypePersonne IN /*('1','3','7')*/
(
SELECT TypePersonne
FROM dbo.Personne
GROUP BY TypePersonne
HAVING COUNT(*) >= 500
)
ORDER BY
TypePersonne,
NomFamille;
-- Requête 3 -- ********* -- Afficher les personnes pour lesquelles on connaît à la fois : une adresse courriel, un numéro de téléphone, le type de téléphone. -- Afficher seulement les personnes dont le type de téléphone appartient aux types réellement utilisés par plus de 100 personnes. -- On affichera : -- l’identifiant de la personne -- le prénom -- le nom de famille -- l’adresse courriel -- le numéro de téléphone -- le type de téléphone. -- Trier les résultats par le nom de famille -- Vote code ici SELECT p.IDEntiteAffaires, p.Prenom, p.NomFamille, ac.AdresseCourriel, tp.NumeroTelephone, tnt.Nom AS TypeTelephone FROM dbo.Personne p INNER JOIN dbo.AdresseCourriel ac ON p.IDEntiteAffaires = ac.IDEntiteAffaires INNER JOIN dbo.TelephonePersonne tp ON p.IDEntiteAffaires = tp.IDEntiteAffaires INNER JOIN dbo.TypeNumeroTelephone tnt ON tp.IDTypeNumeroTelephone = tnt.IDTypeNumeroTelephone WHERE ac.AdresseCourriel IS NOT NULL AND tp.NumeroTelephone IS NOT NULL AND tnt.IDTypeNumeroTelephone IS NOT NULL AND tnt.IDTypeNumeroTelephone IN ( SELECT IDTypeNumeroTelephone FROM dbo.TelephonePersonne GROUP BY IDTypeNumeroTelephone HAVING COUNT(*) > 100 ) ORDER BY p.NomFamille;
-- Requête 4 -- ********* -- Afficher les adresses liées à une entité d’affaires et dont le type d’adresse est utilisé par plus de 1 000 entités. -- On affichera : -- L’identifiant de l’entité d’affaires -- la ville -- le code postal -- le nom de l’état ou de la province -- le nom du pays ou de la région -- le type d’adresse. -- Le résultat sera trié par le pays, l'état et la ville -- Vote code ici SELECT aea.IDEntiteAffaires, a.Ville, a.CodePostal, ep.Nom AS NomEtatProvince, pr.Nom AS NomPaysRegion, ta.Nom AS TypeAdresse FROM dbo.EntiteAffaires ea INNER JOIN dbo.AdresseEntiteAffaires aea ON ea.IDEntiteAffaires = aea.IDEntiteAffaires INNER JOIN dbo.Adresse a ON aea.IDAdresse = a.IDAdresse INNER JOIN dbo.TypeAdresse ta ON aea.IDTypeAdresse = ta.IDTypeAdresse INNER JOIN dbo.EtatProvince ep ON a.IDEtatProvince = ep.IDEtatProvince INNER JOIN dbo.PaysRegion pr ON ep.CodePaysRegion = pr.CodePaysRegion WHERE aea.IDTypeAdresse IN ( SELECT IDTypeAdresse FROM dbo.AdresseEntiteAffaires GROUP BY IDTypeAdresse HAVING COUNT(*) > 1000 ) ORDER BY pr.Nom, ep.Nom, a.Ville;
-- Requête 5 -- ********* -- Afficher les employés actifs dont le taux horaire courant est supérieur au taux horaire moyen courant de tous les employés actifs. -- On affichera : -- l’identifiant de l’employé -- le prénom -- le nom de famille -- le titre du poste -- le département -- le quart de travail -- le taux horaire courant. -- Attention : pour chaque employé, il faut utiliser seulement son taux horaire le plus récent. -- Trier le réasultat par le taux horaire en ordre décroissant -- Vote code ici SELECT e.IDEntiteAffaires, p.Prenom, p.NomFamille, e.TitrePoste, d.Nom AS NomDepartement, q.Nom AS NomQuartTravail, hp.Taux AS TauxHoraireCourant FROM dbo.Employe e INNER JOIN dbo.Personne p ON e.IDEntiteAffaires = p.IDEntiteAffaires INNER JOIN dbo.HistoriqueDepartementEmploye hde ON e.IDEntiteAffaires = hde.IDEntiteAffaires INNER JOIN dbo.Departement d ON hde.IDDepartement = d.IDDepartement INNER JOIN dbo.QuartTravail q ON hde.IDQuartTravail = q.IDQuartTravail INNER JOIN dbo.HistoriquePaieEmploye hp ON e.IDEntiteAffaires = hp.IDEntiteAffaires WHERE e.EstActuel = 1 AND hde.DateFin IS NULL AND hp.DateChangementTaux = ( SELECT MAX(hp2.DateChangementTaux) FROM dbo.HistoriquePaieEmploye hp2 WHERE hp2.IDEntiteAffaires = e.IDEntiteAffaires ) AND hp.Taux > ( SELECT AVG(hp3.Taux) FROM dbo.Employe e3 INNER JOIN dbo.HistoriquePaieEmploye hp3 ON e3.IDEntiteAffaires = hp3.IDEntiteAffaires WHERE e3.EstActuel = 1 AND hp3.DateChangementTaux = ( SELECT MAX(hp4.DateChangementTaux) FROM dbo.HistoriquePaieEmploye hp4 WHERE hp4.IDEntiteAffaires = e3.IDEntiteAffaires ) ) ORDER BY hp.Taux DESC;
-- Requête 6 -- ********* -- Afficher les départements qui ont un nombre d’employés actifs supérieur au nombre moyen d’employés actifs par département. -- On affichera : -- le nom du département -- le groupe du département -- le nombre d’employés actifs. -- Afficher les départements par nombre d'employés décroissant -- Vote code ici SELECT d.Nom AS NomDepartement, d.NomGroupe, COUNT(e.IDEntiteAffaires) AS NombreEmployesActifs FROM dbo.Departement d INNER JOIN dbo.HistoriqueDepartementEmploye hde ON d.IDDepartement = hde.IDDepartement INNER JOIN dbo.Employe e ON hde.IDEntiteAffaires = e.IDEntiteAffaires WHERE e.EstActuel = 1 AND hde.DateFin IS NULL GROUP BY d.Nom, d.NomGroupe HAVING COUNT(e.IDEntiteAffaires) > ( SELECT AVG(NombreEmployes) FROM ( SELECT COUNT(e2.IDEntiteAffaires) AS NombreEmployes FROM dbo.Departement d2 INNER JOIN dbo.HistoriqueDepartementEmploye hde2 ON d2.IDDepartement = hde2.IDDepartement INNER JOIN dbo.Employe e2 ON hde2.IDEntiteAffaires = e2.IDEntiteAffaires WHERE e2.EstActuel = 1 AND hde2.DateFin IS NULL GROUP BY d2.IDDepartement ) AS SyntheseDepartements ) ORDER BY NombreEmployesActifs DESC;
-- Requête 7 -- ********* -- Afficher les territoires de vente qui respectent les conditions suivantes : -- le territoire a au moins un vendeur rattaché -- les ventes cumulées du territoire sont supérieures à la moyenne des ventes cumulées de tous les territoires -- le territoire est associé à au moins un état ou une province. -- On affichera : -- le nom du territoire -- le groupe du territoire -- le pays ou la région -- le nombre d’états ou provinces associés -- les ventes cumulées de l’année. -- Trier les résultats par ventes cumulées année -- Vote code ici SELECT tv.Nom AS NomTerritoire, tv.Groupe AS GroupeTerritoire, pr.Nom AS NomPaysRegion, COUNT(ep.IDEtatProvince) AS NombreEtatsProvinces, tv.VentesCumuleesAnnee FROM dbo.TerritoireVente tv INNER JOIN dbo.PaysRegion pr ON tv.CodePaysRegion = pr.CodePaysRegion INNER JOIN dbo.EtatProvince ep ON tv.IDTerritoire = ep.IDTerritoire WHERE tv.VentesCumuleesAnnee > ( SELECT AVG(VentesCumuleesAnnee) FROM dbo.TerritoireVente ) AND tv.IDTerritoire IN ( SELECT IDTerritoire FROM dbo.Vendeur WHERE IDTerritoire IS NOT NULL ) GROUP BY tv.IDTerritoire, tv.Nom, tv.Groupe, pr.Nom, tv.VentesCumuleesAnnee HAVING COUNT(ep.IDEtatProvince) >= 1 ORDER BY tv.VentesCumuleesAnnee DESC;
-- Requête 8 -- ********* -- Afficher les vendeurs dont les ventes cumulées de l’année sont supérieures ou égales à leur dernier quota connu. -- On affichera : -- l’identifiant du vendeur -- le prénom -- le nom de famille -- le territoire -- la date du dernier quota -- le dernier quota -- les ventes cumulées de l’année. -- Attention : Le quota le plus récent doit être utilisé pour chaque vendeur. -- Trier les résultats par ventes cumulées année -- Vote code ici SELECT v.IDEntiteAffaires, p.Prenom, p.NomFamille, tv.Nom AS NomTerritoire, hq.DateQuota, hq.QuotaVente AS DernierQuota, v.VentesCumuleesAnnee FROM dbo.Vendeur v INNER JOIN dbo.Personne p ON v.IDEntiteAffaires = p.IDEntiteAffaires INNER JOIN dbo.TerritoireVente tv ON v.IDTerritoire = tv.IDTerritoire INNER JOIN dbo.HistoriqueQuotaVendeur hq ON v.IDEntiteAffaires = hq.IDEntiteAffaires WHERE hq.DateQuota = ( SELECT MAX(hq2.DateQuota) FROM dbo.HistoriqueQuotaVendeur hq2 WHERE hq2.IDEntiteAffaires = v.IDEntiteAffaires ) AND v.VentesCumuleesAnnee >= hq.QuotaVente ORDER BY v.VentesCumuleesAnnee DESC;
-- Requête 9 -- ********* -- Afficher les vendeurs dont le territoire actuel fait partie des territoires ayant eu au moins un historique de territoire actif. -- Afficher uniquement les vendeurs dont les ventes cumulées de l’année sont supérieures à la moyenne des ventes cumulées des vendeurs de leur propre territoire. -- On affichera : -- l’identifiant du vendeur ; -- le prénom ; -- le nom de famille ; -- le territoire actuel ; -- le groupe du territoire ; -- les ventes cumulées de l’année. -- Trier les résultats par le territoire et les ventes cumulées. -- Vote code ici SELECT v.IDEntiteAffaires, p.Prenom, p.NomFamille, tv.Nom AS NomTerritoire, tv.Groupe AS GroupeTerritoire, v.VentesCumuleesAnnee FROM dbo.Vendeur v INNER JOIN dbo.Personne p ON v.IDEntiteAffaires = p.IDEntiteAffaires INNER JOIN dbo.TerritoireVente tv ON v.IDTerritoire = tv.IDTerritoire WHERE v.IDTerritoire IN ( SELECT IDTerritoire FROM dbo.HistoriqueTerritoireVente WHERE DateFin IS NULL ) AND v.VentesCumuleesAnnee > ( SELECT AVG(v2.VentesCumuleesAnnee) FROM dbo.Vendeur v2 WHERE v2.IDTerritoire = v.IDTerritoire ) ORDER BY tv.Nom, v.VentesCumuleesAnnee DESC;
-- Requête 10 -- ********** -- Produire un rapport par pays/région pour les pays/régions qui ont un nombre de personnes localisées supérieur à la moyenne. -- Une personne est considérée comme localisée si elle est liée à une adresse. -- On affichera : -- le pays ou la région -- le nombre de personnes localisées -- le nombre de personnes ayant une adresse courriel -- le nombre de personnes ayant un téléphone -- le nombre de types d’adresse utilisés -- le nombre de territoires de vente associés au pays/région. -- Le rapport doit afficher seulement les pays/régions dont le nombre de personnes localisées est supérieur à la moyenne des personnes localisées par pays/région. -- Trier les résultats par type de motif, puis par nom. -- Vote code ici SELECT pr.Nom AS NomPaysRegion, COUNT(DISTINCT p.IDEntiteAffaires) AS NombrePersonnesLocalisees, ( SELECT COUNT(DISTINCT ac.IDEntiteAffaires) FROM dbo.AdresseCourriel ac INNER JOIN dbo.AdresseEntiteAffaires aea2 ON ac.IDEntiteAffaires = aea2.IDEntiteAffaires INNER JOIN dbo.Adresse a2 ON aea2.IDAdresse = a2.IDAdresse INNER JOIN dbo.EtatProvince ep2 ON a2.IDEtatProvince = ep2.IDEtatProvince WHERE ep2.CodePaysRegion = pr.CodePaysRegion ) AS NombrePersonnesAvecCourriel, ( SELECT COUNT(DISTINCT tp.IDEntiteAffaires) FROM dbo.TelephonePersonne tp INNER JOIN dbo.AdresseEntiteAffaires aea3 ON tp.IDEntiteAffaires = aea3.IDEntiteAffaires INNER JOIN dbo.Adresse a3 ON aea3.IDAdresse = a3.IDAdresse INNER JOIN dbo.EtatProvince ep3 ON a3.IDEtatProvince = ep3.IDEtatProvince WHERE ep3.CodePaysRegion = pr.CodePaysRegion ) AS NombrePersonnesAvecTelephone, COUNT(DISTINCT ta.IDTypeAdresse) AS NombreTypesAdresse, ( SELECT COUNT(*) FROM dbo.TerritoireVente tv WHERE tv.CodePaysRegion = pr.CodePaysRegion ) AS NombreTerritoiresVente FROM dbo.PaysRegion pr INNER JOIN dbo.EtatProvince ep ON pr.CodePaysRegion = ep.CodePaysRegion INNER JOIN dbo.Adresse a ON ep.IDEtatProvince = a.IDEtatProvince INNER JOIN dbo.AdresseEntiteAffaires aea ON a.IDAdresse = aea.IDAdresse INNER JOIN dbo.EntiteAffaires ea ON aea.IDEntiteAffaires = ea.IDEntiteAffaires INNER JOIN dbo.Personne p ON ea.IDEntiteAffaires = p.IDEntiteAffaires INNER JOIN dbo.TypeAdresse ta ON aea.IDTypeAdresse = ta.IDTypeAdresse GROUP BY pr.CodePaysRegion, pr.Nom HAVING COUNT(DISTINCT p.IDEntiteAffaires) > ( SELECT AVG(NombrePersonnesParPays) FROM ( SELECT COUNT(DISTINCT p2.IDEntiteAffaires) AS NombrePersonnesParPays FROM dbo.PaysRegion pr2 INNER JOIN dbo.EtatProvince ep4 ON pr2.CodePaysRegion = ep4.CodePaysRegion INNER JOIN dbo.Adresse a4 ON ep4.IDEtatProvince = a4.IDEtatProvince INNER JOIN dbo.AdresseEntiteAffaires aea4 ON a4.IDAdresse = aea4.IDAdresse INNER JOIN dbo.Personne p2 ON aea4.IDEntiteAffaires = p2.IDEntiteAffaires GROUP BY pr2.CodePaysRegion ) AS MoyennePays ) ORDER BY NombrePersonnesLocalisees DESC;
W3schools
Python.org