Sources MySQL
Sources MySQLConsultez toutes les sources
Nombre d'auteurs : 10, nombre de sources : 21, dernière mise à jour : 9 octobre 2010
Supposons qu'une table ELEMENT et une table CATEGORIE sont composées comme suit :
CREATE
TABLE
`ma_base`
.`CATEGORIE`
(
`id_categorie`
INTEGER
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
`nom_categorie`
VARCHAR
(
45
)
NOT
NULL
,
PRIMARY
KEY
(
`id_categorie`
)
)
ENGINE
=
InnoDB;
CREATE
TABLE
`ma_base`
.`ELEMENT`
(
`id_element`
INTEGER
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
`nom_element`
VARCHAR
(
45
)
NOT
NULL
,
`id_categorie`
INTEGER
UNSIGNED
NOT
NULL
,
PRIMARY
KEY
(
`id_element`
)
,
CONSTRAINT
`FK_ELT_CAT`
FOREIGN
KEY
`FK_ELT_CAT`
(
`id_categorie`
)
REFERENCES
`categorie`
(
`id_categorie`
)
ON
DELETE
CASCADE
ON
UPDATE
CASCADE
)
ENGINE
=
InnoDB;
Le but de la requête est de ramener les n premiers éléments de chaque catégorie par ordre d'identifiant. Pour cela, on fait ce qu'on appelle une division relationnelle, comme suit :
SELECT
e.id_element, e.nom_element, c.id_categorie, c.nom_categorie
FROM
ELEMENT e
INNER
JOIN
CATEGORIE c ON
e.id_categorie =
c.id_categorie
WHERE
(
SELECT
COUNT
(*)
FROM
ELEMENT e1
WHERE
e1.id_categorie =
e.id_categorie
AND
e1.id_element <
e.id_element
)
<
n
Il suffit de remplacer n par la valeur souhaitée.
Pour obtenir les n derniers éléments de chaque catégorie, il suffit d'inverser le sens de l'inégalité dans la sous-requête :
SELECT
e.id_element, e.nom_element, c.id_categorie, c.nom_categorie
FROM
ELEMENT e
INNER
JOIN
CATEGORIE c ON
e.id_categorie =
c.id_categorie
WHERE
(
SELECT
COUNT
(*)
FROM
ELEMENT e1
WHERE
e1.id_categorie =
e.id_categorie
AND
e1.id_element >
e.id_element
)
<
n
Attention, cette requête ne fonctionne qu'avec une version de MySQL supportant les sous-requêtes (version 4.1 ou postérieure).
MySQL autorise les jointures externes à gauche (LEFT [OUTER] JOIN) et à droite (RIGHT [OUTER] JOIN), mais pas la jointure externe totale. Cette jointure ramène toutes les valeurs des tables jointes, complétant les colonnes de l'une par NULL quand il n'y a pas de correspondance avec l'autre table.
CREATE
TABLE
tableA (
id INT
(
10
)
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
nom varchar
(
45
)
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
CREATE
TABLE
tableB (
id INT
(
10
)
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
nom varchar
(
45
)
NOT
NULL
,
PRIMARY
KEY
(
id)
)
;
INSERT
INTO
tableA (
nom)
VALUES
(
'1'
)
, (
'2'
)
, (
'4'
)
, (
'5'
)
, (
'6'
)
, (
'6'
)
, (
'8'
)
;
INSERT
INTO
tableB (
nom)
VALUES
(
'1'
)
, (
'3'
)
, (
'4'
)
, (
'4'
)
, (
'7'
)
, (
'7'
)
, (
'8'
)
;
On souhaite obtenir toutes les lignes des tables A et B ayant un nom identique, ainsi que les lignes de A sans nom équivalent dans B et les lignes de B sans nom équivalent dans A.
SELECT
a.nom, b.nom
FROM
tableA a
LEFT
OUTER
JOIN
tableB b ON
a.nom =
b.nom
UNION
ALL
SELECT
a.nom, b.nom
FROM
tableA a
RIGHT
OUTER
JOIN
tableB b ON
a.nom =
b.nom
WHERE
a.nom IS
NULL
Cette requête suppose que la version de MySQL supporte la clause UNION (MySQL version 4.0 minimum).
La syntaxe de cette requête a été trouvée sur ce site.
MySQL n'a pas de fonction pour agréger par produit. Toutefois, il est possible de le faire avec les fonctions EXP et LN.
CREATE
TABLE
Exemple (
forme varchar
(
20
)
,
dimension
varchar
(
10
)
,
facteur float
NOT
NULL
)
;
INSERT
INTO
Exemple VALUES
(
'parallélépipède'
, 'largeur'
, 10
)
;
INSERT
INTO
Exemple VALUES
(
'parallélépipède'
, 'longueur'
, 30
)
;
INSERT
INTO
Exemple VALUES
(
'parallélépipède'
, 'hauteur'
, 15
)
;
INSERT
INTO
Exemple VALUES
(
'pyramide'
, 'base'
, 20
)
;
INSERT
INTO
Exemple VALUES
(
'pyramide'
, 'hauteur'
, 30
)
;
INSERT
INTO
Exemple VALUES
(
'pyramide'
, 'constante'
, 1
/
3
)
;
n veut calculer le volume de chaque forme, et donc faire quelque chose comme :
-- erreur de syntaxe
SELECT
forme, Produit(
facteur)
AS
Volume
FROM
Exemple
GROUP
BY
forme
Cette requête n'est pas valide parce que la fonction Produit() n'existe pas.
on la remplacera donc par l'exponentiel d'une somme de logarithmes :
SELECT
forme, EXP
(
SUM
(
LN
(
facteur)))
AS
Volume
FROM
Exemple
GROUP
BY
forme