Bonjour,

Je vous propose un nouvel élément à utiliser : Obtenir les n premiers éléments de chaque catégorie

Supposons qu'une table ELEMENT et une table CATEGORIE sont composées comme suit :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
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 :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
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).

Qu'en pensez-vous ?