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.

SQLpro, c'est aussi un spécialiste SQL à votre service :
expertise, audit, conseil, assistance, formation,
analyse, modélisation & développement...

LE SQL de A à Z

LE PETIT JEU DES REQUÊTES ...

Ce petit jeu consiste a écrire la plus élégante requête répondant à la question posée.
Voici différentes questions, appelant des réponses devant être écrites à partir de requêtes SQL en utilisant le plus souvent possible le jeu de commande du SQL 2 normalisé (92).

Pour répondre à ce petit jeu, rien de plus simple : envoyez mois vos réponse en utilisant le lien hypertexte ouvrant votre messagerie et je vous dirais si vous avez gagné...
mon estime ;-)
 

dernière mise à jour : 

Courriel
Par Frédéric BROUARD
 
 
 

Problème n° 1 - un dans dix

Notre premier problème est intitulé 'un dans dix' et il nous est posé par Joe CELKO...

Une table est composée de 11 colonnes comme suit :
CREATE TABLE Celko1in10 
(LaClef INTEGER NOT NULL, 
 f1 INTEGER NOT NULL, 
 f2 INTEGER NOT NULL, 
 f3 INTEGER NOT NULL, 
 f4 INTEGER NOT NULL, 
 f5 INTEGER NOT NULL, 
 f6 INTEGER NOT NULL, 
 f7 INTEGER NOT NULL, 
 f8 INTEGER NOT NULL, 
 f9 INTEGER NOT NULL, 
 f10 INTEGER NOT NULL)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (4, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (5, -11, 22, 148, 12547, 0, -4580, 33, 0, 1, 0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (6,  23,  47,  -5,   0,  32,   7,  18,  -9,   0,  99)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (7,   0,   1,   0,   1,   0,   0,   0,   0,   0,   1)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (8,   1,   0,   0,   0,   0,   0 ,  0,   0,   0,   0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (9,   0,  -1,   1,   1,   0,   0,   0,   0,   0,   0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (10,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0)
INSERT INTO Celko1in10 (LaClef, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) VALUES (11, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0)
LaClef f1     f2     f3     f4     f5     f6     f7     f8     f9     f10 
------ ------ ------ ------ ------ ------ ------ ------ ------ ------ -------
1      0      1      1      0      0      0      0      0      0      0
2      0      0      0      0      0      0      0      1      0      0
3      0      1      2      3      4      5      6      7      8      9
4      0      0      0      0      0      -1     1      0      0      0
5      -11    22     148    12547  0      -4580  33     0      1      0
6      23     47     -5     0      32     7      18     -9     0      99
7      0      1      0      1      0      0      0      0      0      1
8      1      0      0      0      0      0      0      0      0      0
9      0      -1     1      1      0      0      0      0      0      0
10     0      0      0      0      0      0      0      1      0      0
11     0      0      0      -1     0      0      0      0      0      0

Il semble que le concepteur de cette base de données veuille stocker des tableaux d'entiers à 10 cellules. Le problème qui est soulevé, c'est que notre quidam veut obtenir en une seule requête les lignes de la table dont toutes les cellules sont à zéro sauf une !

Voici une des solutions proposées par Joe Celko :
 
SELECT *
FROM Celko1in10
WHERE Sign(f1) + Sign(f2) + Sign(f3) + Sign(f4) + Sign(f5) + Sign(f6) + Sign(f7) + Sign(f8) + Sign(f9) + Sign(f10) = 1

Cette solution utilise la fonction 'Sign()' (que l'on trouve dans Sybase par exemple) et qui retourne -1, 0 or +1 si l'argument est négatif, zéro, or positif... Mais elle suppose que les valeurs des colonnes soient des entiers positifs ce qui n'est pas le cas...

Sauriez vous être plus malin encore que Joe Celko ???
Pour ma part j'ai trouvé quelques solutions amusantes, dont une requête de 3 clauses qui utilise un SQL très basic...
A vous de jouer !

Répondre à "Celko 1 dans 10"
 
 

Problème n°2 - le publipostage

Notre second problème est intitulé 'le publipostage' et il m'a été suggéré par Larry DiGiovanni...

Nous disposons d'une table contenant les noms et adresses de personnes (table PERSON) doté d'une colonne NOMBRE. Le but étant de fournir une réponse dans laquelle chaque ligne de la table PERSON est recopié autant de fois que spécifié dans NOMBRE.

La table PERSON a la structure suivante :
CREATE TABLE person
(NOM CHAR(32) NOT NULL,
 VILLE CHAR(32),
 NOMBRE INTEGER)
INSERT INTO person (NOM, VILLE, NOMBRE) values ('MARTIN', 'PARIS', 3)
INSERT INTO person (NOM, VILLE, NOMBRE) values ('DUPOND', 'STRASBOURG', 2)
NOM     VILLE       NOMBRE
------  ----------  ------
MARTIN  PARIS            2
DUPOND  STRASBOURG       3

Comment faire, en UNE requête et une seule, pour obtenir la réponse :
 
NOM     VILLE
------  ----------
DUPOND  STRASBOURG
DUPOND  STRASBOURG
DUPOND  STRASBOURG
MARTIN  PARIS
MARTIN  PARIS

Vous ne pouvez pas modifier la structure, mais vous avez le droit de vous aider en utilisant ou en créant d'autres éléments dans la base de données...
A vous de jouer !

Répondre à Publipostage
 
 

Problème n° 3 - la date an 2000

Ce troisième problème "intitulé date an 2000" est inspiré des petits tracas que l'arrivée de l'an 2000 a laissé à nos développeurs.

Nous disposons d'une colonne intitulé 'FIN AMORT' dans une table comptable, mais cette colonne est en fait de type CHAR(6) et contient des données formatée de la façon suivante : YYMMJJ afin de pouvoir trier facilement sur l'ordre alpha correspondant dans ce cas à l'ordre calendaire.

Notre développeur a décidé d'ajouter une nouvelle colonne 'FIN_AMORT_Y2K' de type DATE cette fois, et aimerais votre aide pour rétablir toutes les anciennes dates au bon format. Aucune date n'est antérieure au 1/1/1960. Sauriez vous l'aider ???
Je vous précise que la date doit être stockée dans cette base de données sous la forme MM-JJ-AAAA (format US).

Voici un extrait des données de cette table intitulé AMORTISSEMENT :
 
FIN_AMORT   FIN_AMORT_Y2K
---------   -------------
990601
970201
021201
941101
920715
CREATE TABLE AMORTISSEMENT
(FIN_AMORT CHAR(6),
 FIN_AMORT_Y2K CHAR(10))
INSERT INTO AMORTISSEMENT (FIN_AMORT) values ('990601')
INSERT INTO AMORTISSEMENT (FIN_AMORT) values ('970201')
INSERT INTO AMORTISSEMENT (FIN_AMORT) values ('021201')
INSERT INTO AMORTISSEMENT (FIN_AMORT) values ('941101')
INSERT INTO AMORTISSEMENT (FIN_AMORT) values ('920715')

Et voici le résultat attendu :
 
FIN_AMORT   FIN_AMORT_Y2K
---------   -------------
990601      06-01-1999
970201      02-01-1997
021201      12-01-2002
941101      11-01-1994
920715      07-15-1992

Répondre à AN 2000
 
 

Problème n° 4 - les chambres libres

Ceproblème "chambres libres" m'a été inspiré par un internaute qui se posait la question suivante : " il me faut gerer les 350 jours de l'année pour des réservations hotelières. Par exemple, il faudrait pouvoir afficher les chambres libre du 22/03/2000 au 15/04/2000 "

Nous avions convenu de modélier cela dans deux tables : la table CHAMBRE, contenant, entre autres, le n° des différentes chambres existantes et une table PLANNING contenant 3 colonnes, le numero de la chambre, la date et une colonne contenant une représentation booléenne. L'hôtel de notre exemple comporte 8 chambres numérotés de 1 à 8, et la table planning ne contient que des lignes pour les chambres réservées ou occupées (en principe, les chambres libres à une date données ne sont pas représentées dans la table PLANNING, sauf si LIBRE a la valeur True).

Table PLANNING :
JOUR        NO_CH  LIBRE
----------  -----  -----
2000-01-11      2  False
2000-01-11      3  False
2000-01-11      4  False
2000-01-11      7  False
2000-01-12      1  False
2000-01-12      4  False
2000-01-12      5  False
2000-01-13      1  False
2000-01-13      2  False
2000-01-13      8  True
2000-01-14      5  False
CREATE TABLE CHAMBRE
(NO_CH INTEGER)
INSERT INTO CHAMBRE VALUES (1)
INSERT INTO CHAMBRE VALUES (2)
INSERT INTO CHAMBRE VALUES (3)
INSERT INTO CHAMBRE VALUES (4)
INSERT INTO CHAMBRE VALUES (5)
INSERT INTO CHAMBRE VALUES (6)
INSERT INTO CHAMBRE VALUES (7)
INSERT INTO CHAMBRE VALUES (8)
CREATE TABLE PLANNING
(JOUR DATE,
 NO_CH INTEGER,
 LIBRE CHAR(5))
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-11', 2, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-11', 3, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-11', 4, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-11', 7, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-12', 1, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-12', 4, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-12', 5, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-13', 1, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-13', 2, 'False')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-13', 8, 'True')
INSERT INTO PLANNING (JOUR, NO_CH, LIBRE) VALUES ('2000-01-14', 5, 'False')

Sauriez vous retrouver, à l'aide d'une requête SQL de votre cru, les chambres libres pour la période du 10 au 15 janvier 2000 ?

Répondre au Chambres Libres
 
 

Problème n° 5 - dates d'anniversaire

Ce problème "date d'anniversaire" est venu de mon patron, qui m'a dit un jour, comme ça, tout de go, "je voudrais envoyer une carte pour chacun de mes clients afin de lui souhiater un bon anniversaire...".
Fastoche, me suis-je dis. Hélas, j'ai du piannoter un bon moment avant d'arriver à trouver une solution honnête.
Sauriez vous trouver aussi bien, sinon mieux encore que ce que j'ai fait ???

Voici un exemple de la table de nos clients :
 
 
NO_CLI  NOM_CLI    DATE_NAISSANCE_CLI
------  ---------  ------------------
24      HESS       1934-08-30
25      CHATON     1938-12-31
26      PLATONOFF  1960-03-29
27      LETERRIER  1945-08-26
28      MONTEIL    1935-03-23
29      SPITHAKIS  1956-03-31
30      ORELL      1956-01-27
31      MARTINET   1946-10-24
32      RAY        1939-12-20
33      TARSAC     1942-08-14
34      COULOMB    1963-01-01
35      SAVY       1942-10-03
36      DAVID      1922-09-19
37      FORGEOT    1949-09-13
38      BERGER     1946-10-16
39      DOUBLET    1961-03-02
40      MATHIEU    1940-02-24
41      MOURGUES   1953-01-14
42      PIERROT    1933-02-11
44      ZAMPIERO   1945-01-19
45      PASCOT
46      MECHRI     1950-08-11
CREATE TABLE CLIENT
(NO_CLI INTEGER,
 NOM_CLI VARCHAR(16),
 DATE_NAISSANCE_CLI DATE)
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (24, 'HESS', '1934-08-30')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (25, 'CHATON', '1938-12-31')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (26, 'PLATONOFF', '1960-03-29')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (27, 'LETERRIER', '1945-08-26')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (28, 'MONTEIL', '1935-03-23')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (29, 'SPITHAKIS', '1956-03-31')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (30, 'ORELL', '1956-01-27')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (31, 'MARTINET', '1946-10-24')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (32, 'RAY', '1939-12-20')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (33, 'TARSAC', '1942-08-14')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (34, 'COULOMB', '1963-01-01')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (35, 'SAVY', '1942-10-03')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (36, 'DAVID', '1922-09-19')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (37, 'FORGEOT', '1949-09-13')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (38, 'BERGER', '1946-10-16')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (39, 'DOUBLET', '1961-03-02')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (40, 'MATHIEU', '1940-02-24')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (41, 'MOURGUES', '1953-01-14')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (42, 'PIERROT', '1933-02-11')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (44, 'ZAMPIERO', '1945-01-19')
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (45, 'PASCOT', Null)
INSERT INTO CLIENT (NO_CLI, NOM_CLI, DATE_NAISSANCE_CLI) VALUES (46, 'MECHRI', '1950-08-11')

Le problème est, par exemple, d'extraire les clients qui vont avoir leur anniversaire entre le 5 février et le 22 mars en ne partant que de la date de naissance…

A vos requêtes ....

Répondre au Date d'Anniversaire
 
 

Problème n° 6 - énumération

Là il s'agit d'alimenter les nombres de 0 à 9999 dans une table de nom ENTIER contenant un seul champ de type entier et de nom NUM en ne s'aidant que de la seule table contenant dans un champ de type entier et de nom CHIFFRE.. Ah, au fait, j'oubliais, j'ai intitulé ce problème, 'énumération'...

La table ENTIER est ainsi visualisée :
 
CHIFFRE
------
0
1
2
3
4
5
6
7
8
9
CREATE TABLE ENTIER
(CHIFFRE INTEGER)
INSERT INTO ENTIER (CHIFFRE) VALUES (0)
INSERT INTO ENTIER (CHIFFRE) VALUES (1)
INSERT INTO ENTIER (CHIFFRE) VALUES (2)
INSERT INTO ENTIER (CHIFFRE) VALUES (3)
INSERT INTO ENTIER (CHIFFRE) VALUES (4)
INSERT INTO ENTIER (CHIFFRE) VALUES (5)
INSERT INTO ENTIER (CHIFFRE) VALUES (6)
INSERT INTO ENTIER (CHIFFRE) VALUES (7)
INSERT INTO ENTIER (CHIFFRE) VALUES (8)
INSERT INTO ENTIER (CHIFFRE) VALUES (9)

Sauriez vous faire une telle requête avec un seul update ?

Répondre au Enumeration
 
 

Problème n° 7 - le comptage

Voici un problème qui m'a été soumis par un collègue de FRA... Je l'ai intitulé le comptage...
Comment faire en sorte que l'on puisse générer une colonne de comptage allant de 1 à n pour compter chaque occurence de la réponse ?

Autrement dit, notre quidam possède une table "T_PERSONNE", dans laquelle il y a des noms de personne (colonne PRS_NOM) et il voudrait faire en sorte que le résultat soit le suivant :
 
CREATE TABLE T_PERSONNE
(PRS_NOM VARCHAR(16))
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('ABELARD')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('ARMAND')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('BAILLE')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('BELLEMARE')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('BLABLA')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('BROCARD')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('CLAUDE')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('DE MONS')
INSERT INTO T_PERSONNE (PRS_NOM) VALUES ('DESTRÉE')
NUM         PRS_NOM
---         ----------
1           ABELARD
2           ARMAND
3           BAILLE
4           BELLEMARE
5           BLABLA
6           BROCARD
7           CLAUDE
8           DE MONS
9           DESTRÉE
...

Avez vous une idée pour traiter ce problème ?

Répondre au Comptage
 
 

Problème n° 8 - linéarisation

Nous apellerons ce problème "linéarisation"...

Opaz, un internaute me demande : J'ai besoin d'un affichage en ligne plutot qu'en colonne.
Voici mes données ...
CREATE TABLE T_CHAMBRE 
(CHB_ID INTEGER,
 CHB_NUMERO VARCHAR(2))
INSERT INTO T_CHAMBRE (CHB_ID, CHB_NUMERO) VALUES (1, '01')
INSERT INTO T_CHAMBRE (CHB_ID, CHB_NUMERO) VALUES (2, '02')
INSERT INTO T_CHAMBRE (CHB_ID, CHB_NUMERO) VALUES (3, '04')
INSERT INTO T_CHAMBRE (CHB_ID, CHB_NUMERO) VALUES (4, '07')
INSERT INTO T_CHAMBRE (CHB_ID, CHB_NUMERO) VALUES (5, '09')
CREATE TABLE T_CLIENT
(CLI_ID INTEGER,
 CLI_NOM VARCHAR(32))
INSERT INTO T_CLIENT (CLI_ID, CLI_NOM) VALUES (1, 'DUPONT')
INSERT INTO T_CLIENT (CLI_ID, CLI_NOM) VALUES (3, 'DURAND')
INSERT INTO T_CLIENT (CLI_ID, CLI_NOM) VALUES (7, 'DUVAL)
CREATE TABLE T_FACTURE
(FAC_ID INTEGER,
 CLI_ID INTEGER,
 CLI_MONTANT FLOAT,
 CLI_DATE DATE)
INSERT INTO T_FACTURE (FAC_ID, CLI_ID, CLI_MONTANT, CLI_DATE)
VALUES (1, 3, 577.10, '2001-11-12')
INSERT INTO T_FACTURE (FAC_ID, CLI_ID, CLI_MONTANT, CLI_DATE)
VALUES (44, 7, 1547.25, '2001-11-18')

et la requête que je fais :
SELECT COUNT(*) AS NB
FROM T_CHAMBRE
   UNION ALL
SELECT COUNT(*) AS NB
FROM T_CLIENT
   UNION ALL
SELECT COUNT(*) AS NB
FROM  T_FACTURE
NB
----------- 
5
3
2

Il me faudrait un résultat sous cette forme :
NB1   NB2    NB3
----- ------ ------
5     3      2 

Sauriez vous aider Opaz et cela en une seule requête ???

Répondre à la linéarisation
 
 

Problème n° 9 - les trous

Voici un problème envoyé par Guillaume, un internaute, je l'ai apellé "Les Trous" !

" J'ai une table dont la clef primaire est un entier (non auto incrémenté). Je cherche une requête qui me donnerai le premier entier disponible dans la séquence parmi ces clefs.  Par exemple si la table contient les enregistrements dont les clefs sont 1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 14, 15 suite à divers ajouts et suppressions d'enregistrements, je veux que la requête me donne 4...."
 
CREATE TABLE NUMERO
(NUM INTEGER)
INSERT INTO NUMERO (NUM) VALUES (1)
INSERT INTO NUMERO (NUM) VALUES (2)
INSERT INTO NUMERO (NUM) VALUES (3)
INSERT INTO NUMERO (NUM) VALUES (5)
INSERT INTO NUMERO (NUM) VALUES (6)
INSERT INTO NUMERO (NUM) VALUES (8)
INSERT INTO NUMERO (NUM) VALUES (9)
INSERT INTO NUMERO (NUM) VALUES (10)
INSERT INTO NUMERO (NUM) VALUES (11)
INSERT INTO NUMERO (NUM) VALUES (12)
INSERT INTO NUMERO (NUM) VALUES (14)
INSERT INTO NUMERO (NUM) VALUES (15)

Je suppose que Guillaume veut gérer les trous de clefs générés par les suppressions d'enregistrements afin d'en récupérer la place... C'est en général une fort mauvaise idée !!!!
Mais sauriez vous quand même dépanner Guillaume ? Et de plus récupérer TOUS les trous ???  En une seule requête évidemment !

Répondre à Les Trous
 
 
 

Problème n° 10 - symétrie négative

C'est une collègue qui m'a posé ce problème ... que j'ai intitulé symétrie négative !

Dans une application comptable ma collègue avait besoin d'annuler logiquement des lignes de détail liée à une ligne maître. Comme un exemple vaut mieux qu'on long discours, nous prendrons une facture et les lignes afférentes à la facture.
 
CREATE TABLE T_FACTURE
(FAC_NUM  INTEGER,
 FAC_DATE DATE)
INSERT INTO T_FACTURE VALUES(56, '2001-08-11')
INSERT INTO T_FACTURE VALUES(79, '2001-08-17')
INSERT INTO T_FACTURE VALUES(101,'2001-09-01')
CREATE TABLE T_LIGNE_FAC
(LIF_NUM     INTEGER,
 FAC_NUM     INTEGER,
 LIF_ARTICLE VARCHAR(16),
 LIF_MONTANT DECIMAL(16,2))
INSERT INTO T_LIGNE_FAC VALUES(11, 56, 'Cartable', 123.50)
INSERT INTO T_LIGNE_FAC VALUES(13, 56, 'Crayons', 17.52)
INSERT INTO T_LIGNE_FAC VALUES(15, 56, 'Trousse', 29.99)
INSERT INTO T_LIGNE_FAC VALUES(16, 56, 'Feutres', 11.25)
INSERT INTO T_LIGNE_FAC VALUES(18, 56, 'Ardoise', 44.21)
INSERT INTO T_LIGNE_FAC VALUES(19, 79, 'Cigarettes', 21.55)
INSERT INTO T_LIGNE_FAC VALUES(21, 79, 'Whisky', 147.65)
INSERT INTO T_LIGNE_FAC VALUES(22, 79, 'Petite pépé', 12857.59)
INSERT INTO T_LIGNE_FAC VALUES(27, 101, 'Savon', 16.24)
INSERT INTO T_LIGNE_FAC VALUES(28, 101, 'Serviette', 45.00)
INSERT INTO T_LIGNE_FAC VALUES(32, 101, 'Shampoing', 44.22)
INSERT INTO T_LIGNE_FAC VALUES(33, 101, 'Bain moussant', 118.40)

Mais voilà... La facture n°79 doit être annulée et pour ce faire, on doit recopier les lignes de la table T_LIGNE_FAC correspondant à cette facture, tout en répondant à deux critères bien précis :
- la clef de ces nouvelle ligne doit être négative
- l'ordre de ces nouvelles lignes doit être le même que les lignes d'origine...

Sauriez vous faire cela en une seule requête ?

A vous de jouer !
 

Répondre à Symétrie Négative
 
 
 

Problème n° 11 - premiers

En partant d'une simple table contenant les nombre de 0 à 10000, sauriez vous en une seule requête obtenir tous les nombres premiers entre 1 et 10000 ?
 
CREATE TABLE ENTIER
(CHIFFRE INTEGER)
INSERT INTO ENTIER (CHIFFRE) VALUES (0)
INSERT INTO ENTIER (CHIFFRE) VALUES (1)
INSERT INTO ENTIER (CHIFFRE) VALUES (2)
INSERT INTO ENTIER (CHIFFRE) VALUES (3)
INSERT INTO ENTIER (CHIFFRE) VALUES (4)
INSERT INTO ENTIER (CHIFFRE) VALUES (5)
INSERT INTO ENTIER (CHIFFRE) VALUES (6)
INSERT INTO ENTIER (CHIFFRE) VALUES (7)
INSERT INTO ENTIER (CHIFFRE) VALUES (8)
INSERT INTO ENTIER (CHIFFRE) VALUES (9)
INSERT INTO ENTIER (CHIFFRE) VALUES (10)
INSERT INTO ENTIER (CHIFFRE)
SELECT DISTINCT E1.CHIFFRE + (E2.CHIFFRE * 10) + (E3.CHIFFRE * 100) + (E4.CHIFFRE * 1000)
FROM   ENTIER E1
       CROSS JOIN ENTIER E2
       CROSS JOIN ENTIER E3 
       CROSS JOIN ENTIER E4
WHERE  E1.CHIFFRE + (E2.CHIFFRE * 10) + (E3.CHIFFRE * 100) + (E4.CHIFFRE * 1000) BETWEEN 11 AND 1000 

C'est plus facile que cela en à l'air, si l'on se souvient qu'un nombre premier est un nombre qui n'est divisible que par lui même et 1. Ou plutôt qu'un nombre qui n'est pas premier est divisible...

Répondre à Nombre premiers
 
 
 

Problème n° 12 - la traduction

C'est à nouveau Syvain, un internaute qui m'a posé une colle ! Voici ce que Sylvain à posté :
Bonjour, j'ai une table avec trois colonnes : id, langue, titre avec comme clé (id, langue). Je voudrais faire une requete du genre :
SELECT titre, id, langue
FROM   matable
WHERE  "(langue='francais' ou alors langue='anglais' si n'existe pas en francais)"
En gros, je veux les résultats, de préférence en francais, mais je prends aussi ceux qui sont en anglais (et qui n'existent pas en francais)

Est-ce possible ?

Voici le jeu d'essais avec lequel j'ai travaillé. Quelque uns de mes collègues ont trouvé d'élégantes solutions... Sauriez vous trouver une façon de faire ?
CREATE TABLE TRADUCTION
(TITRE  VARCHAR(32),
 ID     INT,
 LANGUE VARCHAR(16))
INSERT INTO TRADUCTION VALUES ('COUCOU TOUT LE MONDE', 1, 'FRANÇAIS')
INSERT INTO TRADUCTION VALUES ('HELLO WORLD',          1, 'ANGLAIS')
INSERT INTO TRADUCTION VALUES ('CAMEMBERT',            2, 'FRANÇAIS')
INSERT INTO TRADUCTION VALUES ('TEA',                  3, 'ANGLAIS')

Répondre à La traduction
 
 
 

Problème n° 13 - les bons joueurs

La question vient d'un forum. Étant anonyme, je vous la donne telle quelle :
Je fait un petit QCM sur internet et g crée 2 tables dans ma base de données MySQL. L'une de ces tables contient les informations sur mes joueurs (nom,prénom,etc..) ainsi que leurs réponses à mes questions (table 1).  L'autre table contient, elle , les réponses justes à mes questions (table2).
J'aimerais savoir si il est possible à l'aide de requètes de comparer ces 2 tables, c'est à dire que j'aimerais comparer les réponses de mes joueurs (table1) aux réponses justes (table2) afin de déterminer les vainqueurs.

Voici comment j'ai supposé que notre quidam avait modélisé ses tables et le jeu d'essais que j'utilise :
CREATE TABLE JOUEUR
(NOM VARCHAR(16)
 REPONSE1 INTEGER,
 REPONSE2 INTEGER,
 REPONSE3 INTEGER,
 REPONSE4 INTEGER,
 REPONSE5 INTEGER)

CREATE TABLE REPONSE
(REPONSE1 INTEGER,
 REPONSE2 INTEGER,
 REPONSE3 INTEGER,
 REPONSE4 INTEGER,
 REPONSE5 INTEGER)

INSERT INTO JOUEUR VALUES ('Pierre',  1, 2, 3, 0, 0)
INSERT INTO JOUEUR VALUES ('Paul',    1, 5, 3, 2, 1)
INSERT INTO JOUEUR VALUES ('Jacques', 0, 3, 3, 2, 2)

INSERT INTO REPONSE VALUES (1, 4, 3, 2, 1)

Sauriez vous trouver une réponse pour qu'en une seule requête apparaisse la réponse suivante :
NOM              BONNE_REPONSE 
---------------- ------------- 
Paul             4
Pierre           2
Jacques          2
???

Répondre à Les bons joueurs
 

Problème n° 14 - tranches d'âge

C'est encore un anonyme qui me pose une question sur le forum SQLpro...

Bonjour,
Sur une table comprenant une date de naissance, je cherche à obtenir le nombre d'enregistrements dont les personnes ont de 1 jour à 18 ans, de 18 à 40 ans et les plus de 40 ans.
Qui peut m'indiquer la requête à effectuer ?

Partons de la table PERSONNE suivante :
CREATE TABLE PERSONNE
(PRS_NOM VARCHAR(16),
 PRS_DATE_NAISSANCE DATE)
INSERT INTO PERSONNE VALUES ('DUPONT', '1930-11-23')
INSERT INTO PERSONNE VALUES ('DUVAL', '1960-01-16')
INSERT INTO PERSONNE VALUES ('DURAND', '1970-04-21')
INSERT INTO PERSONNE VALUES ('DUTOUR', '1982-10-11')
INSERT INTO PERSONNE VALUES ('DUHAMEL', '1986-10-09')
INSERT INTO PERSONNE VALUES ('DUMAS', '1992-11-25')

Sauriez vous répondre à notre internaute et de façon générique, c'est à dire quelle que soit les futures tranches d'âge à gérer ?

Répondre à Tranche d'age
 
 

Problème n° 15 - les articles

"Bouchon", c'est son nom de code sur le forum SQL de www.developpez.com, m'a posé une colle que j'ai résolu en 5 minutes...
Sauriez vous être aussi performant que moi ???

Bonjour,

J'ai une requête qui me retourne plusieurs tuples :
 
SELECT TITRES 
FROM OUVRAGES
TITRE
----------------------------------
Le journal de Raymond 
Le vélo d'Alphonse 
Découvrir l'escalade 
L'âge du capitaine 
Comment dévisser la vis 

J'aimerais, s'il y a un article au début du titre ("LE","LA","L'"), que celui-ci soit retiré de la chaine et se retrouve à la fin de celle-ci et entre parenthèses.

Ce qui donnerait :
TITRE
----------------------------------
journal de Raymond (Le) 
vélo d'Alphonse (Le) 
Découvrir l'escalade 
âge du capitaine (L') 
Comment dévisser la vis 

En évitant le piège de l'article qui se trouverait dans le titre (qu'il ne faut donc pas déplacer).

A priori, je ne vois pas le moyen de le faire en SQL, il me faudrait donc traiter "manuellement" les chaines de caractères en PHP et de surcroît retrier tout le tableau.. Ce qui me semble méchamment lourd tout de même en ressources.

A votre avis, est-ce que je suis condamné à le faire manuellement, ou bien est ce qu'il serait quand même possible de faire cela directement en SQL avec MySQL ?

Bien entendu c'est possible... A vous de trouver !
Voici votre jeu d'essais :
CREATE TABLE OUVRAGES
(TITRE VARCHAR(64))
INSERT INTO OUVRAGES VALUES ('Le journal de Raymond')
INSERT INTO OUVRAGES VALUES ('Le vélo d''Alphonse')
INSERT INTO OUVRAGES VALUES ('Découvrir l''escalade')
INSERT INTO OUVRAGES VALUES ('L''âge du capitaine')
INSERT INTO OUVRAGES VALUES ('Comment dévisser la vis')

Allez, je vais vous mettre sur la voie... Rien ne vous empêche de créer une table supplémentaire !

Sauriez vous répondre à notre internaute ?

Répondre à Les Articles
 

Problème n° 16 - Tri alphabétique

Voici encore un problème de tri... Il m'a été posé par un internaute sur le forum SQL de www.developpez.com.

Notre internaute voulait trier les titres de ses livres par ordre aplhabétique et laisser tous ceux qui ne commençent pas par une lettre à la fin.
Sauriez vous lui répondre ?

Exemple :
CREATE TABLE T_LIVRE
(LIV_ID     INTEGER NOT NULL PRIMARY KEY,
 LIV_TITRE  VARCHAR(64))
INSERT INTO T_LIVRE VALUES (1, 'À la recherche du temps perdu')
INSERT INTO T_LIVRE VALUES (2, 'La bible')
INSERT INTO T_LIVRE VALUES (3, '2001 l'odyssée de l''espace')
INSERT INTO T_LIVRE VALUES (4, 'ben hur')
INSERT INTO T_LIVRE VALUES (5, '!Tora Tora Tora')
INSERT INTO T_LIVRE VALUES (6, 'Andrei Roublev')
INSERT INTO T_LIVRE VALUES (7, '')

Si vous avez brillament répondu à notre précédent puzzle, alors vous devriez solutionner celui là !

Voici le résultat attendu :
 
LIV_ID  LIV_TITRE
------- -------------------------------------
1       À la recherche du temps perdu
6       Andrei Roublev 
4       ben hur
2       La bible
3       2001 l'odyssée de l''espace
5       !Tora Tora Tora

Répondre à Tri alphabétique
 

Problème n° 17 - Apparition

Cette demande qui m'a donné du fil à retordre provient du forum SQL du site www.developpez.com que j'anime.
Il s'agit de récupérer les valeurs de la colonne A pour laquelle les données de la colonne B sont les mêmes qu'une autre valeur de la colonne A.
 
CREATE TABLE AB 
(A CHAR(2), 
 B CHAR(2)) 
INSERT INTO AB VALUES ('A1', 'B1') 
INSERT INTO AB VALUES ('A1', 'B2') 
INSERT INTO AB VALUES ('A2', 'B1') 
INSERT INTO AB VALUES ('A2', 'B3') 
INSERT INTO AB VALUES ('A3', 'B1') 
INSERT INTO AB VALUES ('A3', 'B3') 
INSERT INTO AB VALUES ('A3', 'B7') 
INSERT INTO AB VALUES ('A3', 'B4') 
INSERT INTO AB VALUES ('A4', 'B1') 
INSERT INTO AB VALUES ('A4', 'B3') 
INSERT INTO AB VALUES ('A5', 'B2') 
INSERT INTO AB VALUES ('A6', 'B1') 
INSERT INTO AB VALUES ('A6', 'B4') 
INSERT INTO AB VALUES ('A6', 'B7') 
INSERT INTO AB VALUES ('A6', 'B3') 
INSERT INTO AB VALUES ('A8', 'B1') 
INSERT INTO AB VALUES ('A8', 'B4') 
INSERT INTO AB VALUES ('A8', 'B7') 
INSERT INTO AB VALUES ('A8', 'B3') 
INSERT INTO AB VALUES ('A9', 'B1') 
INSERT INTO AB VALUES ('A9', 'B4') 
INSERT INTO AB VALUES ('A9', 'B8') 
INSERT INTO AB VALUES ('A9', 'B3') 

Ici les seuls résulats valables sont A2 et A4 et A3 d'un côté et A6 et A8 de l'autre.

En effet les données de la colonne B sont identiques pour A2 et A4, soit B1 et B3.
Les données de la colonne B sont aussi identiques pour A3, A6 et A8, soit B1, B3, B7, B4

Le résultat doit donc être :
A
--
A2
A3
A4
A6
A8

Simple en apparence, ce problème est assez complexe....

Répondre à Apparition
 

Problème n° 18 - Meilleure correspondance partielle

Voici une question qui m'a été posée sur le forum SQL de www.developpez.com par neness...

Je possède une table T_ROUTE :
CREATE TABLE T_ROUTE
(RTE_DESTINATION varchar(32), 
 RTE_CODE        char(16))

Ainsi remplie :
INSERT INTO T_ROUTE VALUES ('albania-Mobile', '0035538') 
INSERT INTO T_ROUTE VALUES ('albania-Mobile', '0035569') 
INSERT INTO T_ROUTE VALUES ('albania-Mobile', '0035560') 
INSERT INTO T_ROUTE VALUES ('SFR-Mobile',     '0077280') 
INSERT INTO T_ROUTE VALUES ('SFR-Mobile',     '0077390') 
INSERT INTO T_ROUTE VALUES ('BOUYGE_TEL',     '0078452')

Pour chaque Destination, je recherche la partie de la colonne "code" dont les données sont communes.
Dans l'exemple donné, la requête doit renvoyer :
 
RTE_DESTINATION      RTE_CODE
-------------------- --------------- 
albania-Mobile       00355
BOUYGE_TEL           0078452
SFR-Mobile           0077

C'est à dire une seule route par destination, correspondant aux premiers caractères communs à toutes les occurences de la colonne RTE_CODE.

Comment faire ?

Répondre à Meilleure correspondance partielle
 

Problème n° 19 - La médiane

Dans un forum consacré à SQL Server de Microsoft, j'ai trouvé cette question forte intéressante :
Bonjour,
Je doit calculer des données statistiques et la médiane est absente...
Comment cela peut il être réalisé en une requête ?.

Voici le jeu de données que j'ai utilisé pour la solution :
 
CREATE TABLE STATISTIQUES
(STAT_ID     INT NOT NULL PRIMARY KEY,
 STAT_VALEUR DECIMAL(5,2) NOT NULL)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (1, 62.96)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (2, 65.53)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (3, 65.85)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (4, 66.20)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (5, 58.27)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (6, 74.54)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (7, 74.95)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (8, 75.22)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (9, 78.16)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (10, 84.27)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (11, 89.92)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (12, 90.29)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (13, 90.56)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (14, 91.26)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (15, 94.14)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (16, 25.73)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (17, 38.57)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (18, 38.89)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (19, 53.01)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (20, 53.36)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (21, 53.65)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (22, 64.62)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (23, 64.71)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (24, 66.13)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (25, 66.60)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (26, 66.86)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (27, 67.59)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (28, 68.35)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (29, 90.91)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (30, 91.11)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (31, 94.49)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (32, 94.87)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (33, 97.14)
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (34, 99.59)

La solution étant :
STAT_ID     STAT_VALEUR 
----------- ----------- 
27          67.59
28          68.35

et si l'on rajoute la ligne :
INSERT INTO STATISTIQUES (STAT_ID, STAT_VALEUR) VALUES (35, 50.05)

La solution devient :
STAT_ID     STAT_VALEUR 
----------- ----------- 
27          67.59

Répondre à La médiane
 
 

Problème n° 20 - Insertion en bloc

Voici un problème intéressant pour s'affanchir de certaines procédures stockées bêtes et méchante...Comment insérer de multiple ligne, par exemple dans une table de jointure, sans faire appel à une boucle et à l'aide d'une seule et unique requête ?

Notre problème est le suivant :

Soit la table des caractères suivants :
CREATE TABLE T_CAR
(CAR CHAR(1) NOT NULL PRIMARY KEY)

Contenant par exemple :

INSERT INTO T_CAR VALUES (' ')
INSERT INTO T_CAR VALUES ('0')
INSERT INTO T_CAR VALUES ('1')
INSERT INTO T_CAR VALUES ('2')
INSERT INTO T_CAR VALUES ('3')
INSERT INTO T_CAR VALUES ('4')
INSERT INTO T_CAR VALUES ('5')
INSERT INTO T_CAR VALUES ('6')
INSERT INTO T_CAR VALUES ('7')
INSERT INTO T_CAR VALUES ('8')
INSERT INTO T_CAR VALUES ('9')
INSERT INTO T_CAR VALUES ('A')
INSERT INTO T_CAR VALUES ('B')
INSERT INTO T_CAR VALUES ('C')
...
INSERT INTO T_CAR VALUES ('z')

et la table listant toutes les colonnes d'une base de donnée
CREATE TABLE T_COLONNE_COL
(COL_ID   INTEGER NOT NULL PRIMARY KEY,
 COL_NAME CHAR(128))

Contenant par exemple
INSERT INTO T_COLONNE_COL VALUES (33, 'REF_MODELE')

Alors, la table de jointure
CREATE TABLE TJ_FORMATCOL_FMC
(COL_ID INTEGER NOT NULL FOREIGN KEY REFERENCES T_CAR (CAR),
 CAR    CHAR(1) NOT NULL FOREIGN KEY REFERENCES T_COLONNE_COL (COL_ID),
 CONSTRAINT PK_FMC PRIMARY KEY (COL_ID, CAR))
permet de spécifier si la colonne identifié COL_ID est autorise de stocker des chaines contenant tel ou tel caractères

Par exemple, notre utilisateur voudrait que la colonne 33 devant contenir une référence numérique ne soit autorisé qu'à recevoir des caractères "chiffres" de 0 à 9...

Sauriez vous trouver en une seule requête comment procéder à l'insertion massive de ces dix lignes ?

Résultat  TJ_FORMATCOL_FMC ..
COL_ID   CAR
-------- --------
33       0
33       1
33       2
33       3
33       4
33       5
33       6
33       7
33       8
33       9

???

Répondre à Insertion Multiple
 

Problème n° 21 - Ordonner et réordonner !

Un problème d'ordonnancement avec SQL m'a été proposé par Mouse sur le forum SQL de developpez.
Il s'agit de modifier une colonne d'une table assurant l'ordonnacement des données de la table.

Par exemple, la colonne position est numérotée de 1 à 5 et l'on désire remplacer la valeur 4
par la valeur 2 tout en préservant la continuité de l'ordre de 1 à 5...

Un petit exemple permettra de mieux comprendre la chose...

CREATE TABLE MyTable
(id integer,
 position integer)
INSERT INTO MyTable VALUES (1, 1 )
INSERT INTO MyTable VALUES (2, 2 )
INSERT INTO MyTable VALUES (3, 3 )
INSERT INTO MyTable VALUES (4, 4 )
INSERT INTO MyTable VALUES (5, 5)
SELECT *
FROM MyTable
id          position   
----------- -----------
1           1
2           2
3           3
4           4
5           5

après changement de position 4 en 2, le jeu de résultat devient :

id          position   
----------- -----------
1           1
2           3
3           4
4           2
5           5

Sauriez vous faire cele en une seule requête ?

Content de ce travail, notre quidam veut aller plus loin et renuméroter ses positions en continuité de 1 à n (n étant le nombre de lignes dans la table) quelque soit les données de la colonne position, mais en gardant toujours le même ordre...

Voici donc les nouvelles conditions du jeu d'essai :

DELETE FROM MyTable
INSERT INTO MyTable VALUES (5,  12)
INSERT INTO MyTable VALUES (18,  8)
INSERT INTO MyTable VALUES (4,  10)
INSERT INTO MyTable VALUES (3,   9)
INSERT INTO MyTable VALUES (12,  4)

Possible ou pas ???

Répondre à Ordonner et Réordonner


Problème n° 22 - Jointure hétérogène multiple

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 parmiè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]... 
Problème... comment réaliser une requête qui fait la jointure entre ces deux tables ?

Voici le jeu d'essais de notre quidam :

CREATE TABLE publics
( IDPublic int NOT NULL PRIMARY KEY,
  Public_Nom varchar(50) NOT NULL default '') 
CREATE TABLE prestation
( IDPrestation int NOT NULL PRIMARY KEY,
  Prestation_Nom varchar(50) NOT NULL default '',
  Prestation_Type varchar(50) NOT NULL default '')
INSERT INTO publics VALUES (1, 'particulier')
INSERT INTO publics VALUES (3, 'entreprise')
INSERT INTO publics VALUES (2, 'groupe')
INSERT INTO prestation VALUES (1, 'Tour en voiture', '[3]')
INSERT INTO prestation VALUES (2, 'Compétition à plusieurs', '[3].[2]')
INSERT INTO prestation VALUES (3, 'Course d''endurance ', '[1].[2]')
INSERT INTO prestation VALUES (4, 'Bapteme ', '[1]')
INSERT INTO prestation VALUES (5, 'Course en tandem ', '[2]')

Sauriez vous, en une seule requête, afficher :

IDPublic    Public_Nom    IDPrestation Prestation_Nom            Prestation_Type
----------- ------------- ------------ ------------------------- ----------------
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]

Répondre à Jointure hétérogène multiple



Problème n° 23 - Insertion conditionnelle

En voila une question intéressante : comment insérer une ligne dans une table, uniquement si elle n'y est pas déjà ?
Autrement dit il me faut une requête capable d'insérer ma ligne si elle n'existe pas, sinon, de na pas procéder à l'insertion...

Pour mieux comprendre la chose voici le modèle de données et les différents jeu d'essais.

CREATE TABLE MATABLE
( COL1 INTEGER
  COL2 VARCHAR(16)) 
INSERT INTO MATABLE VALUES (1, 'toto')
INSERT INTO MATABLE VALUES (1, 'titi')

Pourriez vous :

1) créer une requête INSERT dans cette table avec les valeurs 1, toto et faire en sorte que rien ne soit inséré sans générer d'erreur ?
2) insérer 3, tutu avec cette même requête ??

Répondre à  Insertion conditionnelle



Problème n° 24 - Un arbre à deux niveaux

Posté par the tigrou...,dans le  forum SQL de developpez :

Je dois écrire des requêtes qui font appel à des enregistrements appartenant à des tables differentes.
Par exemple une table "liste entreprise" et une table "liste salarié" (liées ensemble)
comment selectionner les salariés de chaque entreprise de façon a faire une arboresence à deux niveaux ??

Par exemple, la réponse doit être :

NOM              
-----------------
IBM
 Durand
 Dupont
 Dubois
 Duval
EDF
 Dupond
 Duhamel
 Dufour

Pour vous aider, voici le jeu d'essais concocté par mes soins :

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)

A vous de jouer !

Répondre à Arbre à deux niveaux