![]() |
ATTENTION
: le contenu des ces pages web est soumis aux dispositions
légales françaises et internationales en matière de
droits d'auteurs et de copyright.

LE SQL de A à Z
EXERCICES ET TRAVAUX PRATIQUES (3eme partie) ...
Problèmes et exercices corrigés sur le langage SQL.
Voici une série de travaux pratiques sur le langage SQL appelant des réponses devant être écrites uniquement à partir de requêtes, en utilisant le plus souvent possible le jeu de commande du SQL 2 normalisé (1992). Les données de départ, comme la structure des tables en jeu et la réponse attendue sous la forme d'un jeu de résultat (table) sont donné dans chacun des énoncés
Pour
répondre à ces, questions, rien de plus simple :
envoyez-moi vos solutions en utilisant le lien hypertexte ouvrant votre
messagerie. Bien entendu, je vous répond personnellement et vous
propose une correction didactique et pédagogique afin que vous
compreniez le mécanisme de construction de la requête.
Voici
donc une première série d'exercices
numérotés de 21 à 30.
dernière mise à jour :
LES RÈGLES DU JEU
Pour
répondre à la question posée il vous faut
écrire une seule requête SQL. Vous avez le droit d'utiliser
toutes les techniques disponibles dans SQL:2003 :
Vous pouvez
utiliser toutes les opérations disponibles dans SQL, y compris
les sous requêtes dans les clauses SELECT, FROM, WHERE et HAVING,
et bien entendu les sous requêtes corrélées.
Vous pouvez
ajoutez dans la base une ou plusieurs nouvelles tables et leurs
données ou encore définir autant de vues que vous le voulez,pour concourrir
à la solution. En revanche vous n'avez pas le droit d'utiliser
une UDF (fonction utilisateur), ni une procédure stockée,
ni un trigger, ni bien entendu modifier la ou les tables et les
données à l'origine du problème.
Pour vous aider à répondre, nous
vous donnons :
Pour
savoir si votre solution est bonne, comme pour obtenir la solution,
envoyez votre réponse ou votre demande par mail en
précisant le titre ou le n° du problème.
Problème
n° 21 - Ordonner, réordonner !



| CREATE TABLE T_PAYS_PAY (PAY_NOM VARCHAR(16), PAY_POSITION INTEGER); |
INSERT INTO T_PAYS_PAY VALUES
('Allemagne', 1); INSERT INTO T_PAYS_PAY VALUES ('Belgique', 2); INSERT INTO T_PAYS_PAY VALUES ('Croatie', 3); INSERT INTO T_PAYS_PAY VALUES ('Espagne', 4); INSERT INTO T_PAYS_PAY VALUES ('France', 5); INSERT INTO T_PAYS_PAY VALUES ('Grèce', 6); |
| SELECT * FROM T_PAYS_PAY; |
PAY_NOM
PAY_POSITION ---------------- ------------ Allemagne 1 Belgique 2 Croatie 3 Espagne 4 France 5 Grèce 6 |
| PAY_NOM
PAY_POSITION ---------------- ------------ Allemagne 2 Belgique 3 Croatie 4 Espagne 5 France 1 Grèce 6 |
| DELETE FROM T_PAYS_PAY; |
INSERT INTO T_PAYS_PAY VALUES ('Allemagne', 11); INSERT INTO T_PAYS_PAY VALUES ('Belgique', 8); INSERT INTO T_PAYS_PAY VALUES ('Croatie', 9); INSERT INTO T_PAYS_PAY VALUES ('Espagne', 5); INSERT INTO T_PAYS_PAY VALUES ('France', 12); INSERT INTO T_PAYS_PAY VALUES ('Grèce', 7); |
PAY_NOM
PAY_POSITION ---------------- ------------ Espagne 5 Grèce 7 Belgique 8 Croatie 9 Allemagne 11 France 12 |
| PAY_NOM
PAY_POSITION ---------------- ------------ Espagne 1 Grèce 2 Belgique 3 Croatie 4 Allemagne 5 France 6 |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°21 - Ordonner, réordonner"Problème
n° 22 - Jointure hétérogène

Voici un
internaute qui a hérité d'un modèle
particulièrement mal modélisé. En effet, dans l'une
des colonnes de la première table ("public") on trouve toutes les
données relatives aux références de l'autres tables
sous la forme suivante : [clef1].[clef2].[clef3]...
| CREATE TABLE T_PUBLIC_PBL (PBL_ID INTEGER, PBL_NOM VARCHAR(16)); |
INSERT INTO T_PUBLIC_PBL VALUES
(1, 'particulier'); INSERT INTO T_PUBLIC_PBL VALUES (3, 'entreprise'); INSERT INTO T_PUBLIC_PBL VALUES (2, 'groupe'); |
| CREATE TABLE T_PRESTATION_PST (PST_ID INTEGER, PST_LIBELLE VARCHAR(25), PST_PUBLIC VARCHAR(32)); |
INSERT INTO T_PRESTATION_PST
VALUES (1, 'Tour en voiture', '[3]'); INSERT INTO T_PRESTATION_PST VALUES (2, 'Compétition à plusieurs', '[3].[2]'); INSERT INTO T_PRESTATION_PST VALUES (3, 'Course d''endurance ', '[1].[2]'); INSERT INTO T_PRESTATION_PST VALUES (4, 'Bapteme ', '[1]'); INSERT INTO T_PRESTATION_PST VALUES (5, 'Course en tandem ', '[2]'); |
| SELECT * FROM T_PUBLIC_PBL | SELECT * FROM T_PRESTATION_PST |
| PBL_ID
PBL_NOM ----------- ---------------- 1 particulier 3 entreprise 2 groupe |
PST_ID
PST_LIBELLE
PST_PUBLIC
----------- ------------------------- -------------------------------- 1 Tour en voiture [3] 2 Compétition à plusieurs [3].[2] 3 Course d'endurance [1].[2] 4 Bapteme [1] 5 Course en tandem [2] |
| PBL_ID
PBL_NOM PST_ID
PST_LIBELLE
PST_PUBLIC ----------- ------------- ------------ ------------------------- ---------------- 3 entreprise 1 Tour en voiture [3] 2 groupe 2 Compétition à plusieurs [3].[2] 3 entreprise 2 Compétition à plusieurs [3].[2] 1 particulier 3 Course d'endurance [1].[2] 2 groupe 3 Course d'endurance [1].[2] 1 particulier 4 Bapteme [1] 2 groupe 5 Course en tandem [2] |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°22 - Jointure hétérogène"Problème n° 23 - Insertion conditionnelle



| CREATE
TABLE MATABLE ( COL1 INTEGER, COL2 VARCHAR(16)) |
INSERT INTO MATABLE VALUES (1,
'toto') INSERT INTO MATABLE VALUES (1, 'titi') |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°23 - Insertion conditionnelle"Problème
n° 24 - Un arbre à deux niveaux

| CREATE TABLE T_ENTREPRISE_ETP (ETP_ID INTEGER NOT NULL PRIMARY KEY, ETP_NOM VARCHAR(16)) |
CREATE TABLE T_EMPLOYEE_EMP (EMP_ID INTEGER NOT NULL PRIMARY KEY, EMP_NOM VARCHAR(16), ETP_ID INTEGER NOT NULL FOREIGN KEY REFERENCES T_ENTREPRISE_ETP (ETP_ID)) |
| INSERT INTO T_ENTREPRISE_ETP VALUES (1, 'IBM') INSERT INTO T_ENTREPRISE_ETP VALUES (2, 'EDF') |
INSERT INTO T_EMPLOYEE_EMP VALUES (1, 'Durand', 1) INSERT INTO T_EMPLOYEE_EMP VALUES (2, 'Dupont', 1) INSERT INTO T_EMPLOYEE_EMP VALUES (3, 'Dubois', 1) INSERT INTO T_EMPLOYEE_EMP VALUES (4, 'Duval', 1) INSERT INTO T_EMPLOYEE_EMP VALUES (5, 'Dupond', 2) INSERT INTO T_EMPLOYEE_EMP VALUES (6, 'Duhamel', 2) INSERT INTO T_EMPLOYEE_EMP VALUES (7, 'Dufour', 2) |
| NOM ----------------- IBM Durand Dupont Dubois Duval EDF Dupond Duhamel Dufour |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°24 - Arbre à deux niveaux"Problème n° 25 - Éclater des lignes





| CREATE
TABLE LIGNE (ID_LIGNE INTEGER, ID_REF INTEGER, QUANTITE INTEGER); |
INSERT INTO LIGNE (ID_LIGNE,
ID_REF, QUANTITE) VALUES (1, 1, 4); INSERT INTO LIGNE (ID_LIGNE, ID_REF, QUANTITE) VALUES (2, 2, 1); INSERT INTO LIGNE (ID_LIGNE, ID_REF, QUANTITE) VALUES (3, 3, 2); INSERT INTO LIGNE (ID_LIGNE, ID_REF, QUANTITE) VALUES (4, 1, 1); INSERT INTO LIGNE (ID_LIGNE, ID_REF, QUANTITE) VALUES (5, 2, 2); INSERT INTO LIGNE (ID_LIGNE, ID_REF, QUANTITE) VALUES (6, 4, 2); |
| SELECT * FROM LIGNE ORDER BY ID_REF |
ID_LIGNE
ID_REF QUANTITE ----------- ----------- ----------- 1 1 4 4 1 1 5 2 2 2 2 1 3 3 2 6 4 2 |
| ID_ARTICLE
ID_REF
SERIE ID_LIGNE ----------- ----------- ----------- ----------- 1 1 1 1 2 1 2 1 3 1 3 1 4 1 4 1 5 1 5 4 6 2 1 2 7 2 2 5 8 2 3 5 9 3 1 3 10 3 2 3 11 4 1 6 12 4 2 6 |
| ID_REF
ID_LIGNE QUANTITE ----------- ----------- ----------- 1 1 4 1 1 4 1 1 4 1 1 4 1 4 1 2 2 1 2 5 2 2 5 2 3 3 2 3 3 2 4 6 2 4 6 2 |
ID_REF ID_LIGNE
SERIE ID_ARTICLE ----------- ----------- ----------- ----------- 1 1 1 1 1 1 2 2 1 1 3 3 1 1 4 4 1 4 5 5 2 2 1 6 2 5 2 7 2 5 3 8 3 3 1 9 3 3 2 10 4 6 1 11 4 6 2 12 |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°25 - Éclater des lignes"Problème n° 26 - Noms incrémentés


| CREATE
TABLE T_UTILISATEUR_USR (USR_ID INTEGER NOT NULL PRIMARY KEY, USR_NOM CHAR(16) NOT NULL UNIQUE); |
INSERT INTO T_UTILISATEUR_USR
VALUES (1, 'DUPONT'); INSERT INTO T_UTILISATEUR_USR VALUES (2, 'DURAND'); INSERT INTO T_UTILISATEUR_USR VALUES (3, 'DURAND1'); |
| SELECT * FROM T_UTILISATEUR_USR |
USR_ID
USR_NOM ----------- ---------------- 1 DUPONT 2 DURAND 3 DURAND1 |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°26 - Noms incrémentés"Problème n° 27 - Une lettre un nom



| CREATE
TABLE T_CONTACT_CTC (CTC_NOM VARCHAR(32)); |
INSERT INTO T_CONTACT_CTC VALUES
('Aaron'); INSERT INTO T_CONTACT_CTC VALUES ('Abel'); INSERT INTO T_CONTACT_CTC VALUES ('Babet'); INSERT INTO T_CONTACT_CTC VALUES ('Boudet'); INSERT INTO T_CONTACT_CTC VALUES ('Brouard'); INSERT INTO T_CONTACT_CTC VALUES ('Cabu'); INSERT INTO T_CONTACT_CTC VALUES ('Cortès'); INSERT INTO T_CONTACT_CTC VALUES ('Cardeau'); INSERT INTO T_CONTACT_CTC VALUES ('Zoltan'); |
| LETTRE CTC_NOM --------- ------------------------- A Aaron B Babet C Cabu ... Z Zoltan |
| variante 1 : obtenir les noms des "secondes" personnes |
LETTRE
CTC_NOM ------ -------------------------------- A Aaron B Babet C Cabu Z Zoltan |
| variante 2 : (n = 3) |
LETTRE
CTC_NOM ------ -------------------------------- B Brouard C Cortès |
| variante 3 : (n = 2) obtenir les noms des niemes personnes, mais si elle n'existe pas, alors la dernière ! |
LETTRE
CTC_NOM ------ -------------------------------- A Abel B Boudet C Cardeau Z Zoltan |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°27 - Une lettre un nom"Problème n° 28 - Filtrer les adresses IP




Pêché
sur le forum SQL de www.developpez.com :
Bonjour
à tous,
je
travaille sur des adresses IP et je n'arrive pas a faire une selection
comme ceci dans une requête sql :
Select adresseSource
from Y
where 10.120.12.1 <= adresseSource <= 10.130.23.1
- 10.120.12.1
correspont à l'attribut DebutIPValide dans la table X
-
10.130.23.1 correspond à l'attribut FinIPValide dans la table X
adresseSource
fait parti de la table Y
Merci
pour vos suggestions
| CREATE
TABLE TIP (TIP_ADR VARCHAR(15)); |
INSERT INTO TIP VALUES
('10.120.12.1'); INSERT INTO TIP VALUES ('10.130.23.1'); INSERT INTO TIP VALUES ('10.130.201.1'); INSERT INTO TIP VALUES ('10.13.11.1'); |
| TIP_ADR ------------------- 10.120.12.1 10.130.23.1 |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°28 - Filtrer les adresses IP"Problème n° 29 - Calculer l'adresses IP suivante




L'exercice
précédent m'a donné l'idée d'un exercice
complémentaire...
Partant d'une table de machines ayant des adresses IP, cette fois ci
bien modélisées, comment trouver l'adresse IP suivante
pour insérer une nouvelle machine ?
| CREATE
TABLE T_MACHINE_MAC (MAC_ID INT NOT NULL PRIMARY KEY, MAC_NOM VARCHAR(16), MAC_ADRIP1 SMALLINT CHECK(MAC_ADRIP1 BETWEEN 0 AND 255), MAC_ADRIP2 SMALLINT CHECK(MAC_ADRIP2 BETWEEN 0 AND 255), MAC_ADRIP3 SMALLINT CHECK(MAC_ADRIP3 BETWEEN 0 AND 255), MAC_ADRIP4 SMALLINT CHECK(MAC_ADRIP4 BETWEEN 0 AND 255) CONSTRAINT CU_ADRIP UNIQUE (MAC_ADRIP1, MAC_ADRIP2, MAC_ADRIP3, MAC_ADRIP4)); |
INSERT INTO T_MACHINE_MAC VALUES
(1, 'PC', 123, 12, 1, 200); INSERT INTO T_MACHINE_MAC VALUES (2, 'PC', 123, 12, 1, 255); INSERT INTO T_MACHINE_MAC VALUES (3, 'PC', 123, 12, 255, 255); INSERT INTO T_MACHINE_MAC VALUES (4, 'PC', 123, 13, 0, 0); INSERT INTO T_MACHINE_MAC VALUES (5, 'PC', 123, 255, 255, 255); |
| MAC_ID
MAC_NOM
NEW_ADRIP1 NEW_ADRIP2 NEW_ADRIP3 NEW_ADRIP4 ----------- ---------------- ----------- ----------- ----------- ----------- 1 PC 123 12 1 201 2 PC 123 12 2 0 3 PC 123 13 0 1 4 PC 123 13 0 1 5 PC 124 0 0 0 |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°29 - Calculer l'adresse IP suivanteProblème n° 30 - Nombre de jours contigus





Pas facile, la
question de Stéphane T...
Y a t il une formule magique qui permet de compter des dates
consécutives en sql ?
Comme vous le savez certainement déjà, cette formule magique est une requête !
Voici les données qui nous servirons de test et la structure de la table associée :| CREATE
TABLE T_PLANNING_PNG (PNG_DATE DATE); |
INSERT INTO T_PLANNING_PNG
VALUES ('2004-01-01'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-02'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-03'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-15'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-16'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-17'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-18'); INSERT INTO T_PLANNING_PNG VALUES ('2004-01-30'); |
| DateDebut
NbJours
--------------- ------------- 2004-01-01 3 2004-01-15 4 2004-01-30 1 |
cliquez sur le mail
pour répondre et titrez votre mail "Problème
n°30 - Nombre de jours contigus