Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/06/2011, 16h25   #1
Invité de passage
 
Sébastien Perso
Inscription : octobre 2010
Messages : 13
Détails du profil
Informations personnelles :
Nom : Sébastien Perso

Informations forums :
Inscription : octobre 2010
Messages : 13
Points : 2
Points : 2
Par défaut Besoin d'aide pour une requête spécifique.

Bonjour,

Je rencontre un soucis pour une requête depuis hier et après plusieurs recherches sur google, je n'arrive toujours pas à solutionner cette énigme !!

Voilà ma configuration :
EaysyPhp installé sur mon poste avec donc MySQL 5.5.10

J'ai deux tables telles que :
Table categorie
id_categorie | intiule_categorie
1 | Faune & Flore
2 | Voyages
3 | Pauses longues
4 | Famille
5 | Sports

Table appartenir
id_photo | id_categorie
10 | 1
11 | 2
12 | 3
13 | 1
14 | 4
15 | 2
16 | 4
17 | 5
18 | 1
19 | 2
20 | 1

Les champs soulignés sont des clés primaires.
La table appartenir fait la jonction entre mes tables photo et categorie, puisque une photo peut appartenir à 1 et plusieurs categorie et vice-versa.

J'aurai besoin de répertorier les 3 dernières catégories de photo utilisées, puis dans un autre calque caché les autres restantes dans l'ordre alphabétique.
J'ai besoin pour cela de récupérer l'ID des categories mais également leurs intitulés pour l'afficher sur la page.

Le résultat de la ou des requêtes devrait donc être : 1(Faune & Flore), 2(Voyages), 5(Sports) ; les autres catégories dans l'ordre alphabétique.

Pour cela la requête que j'utiliserai est donc :
Code :
SELECT DISTINCT id_categorie FROM appartenir ORDER BY id_photo DESC LIMIT 0,3
Le problème est que j'obtiens seulement l'ID des catégories pour le moment.
J'utilise ORDER BY id_photo DESC puisque la table appartenir est alimentée au fur et à mesure des enregistrements de photos et des leurs catégories respectives.


J'ai tenté une seconde requête mais sans résultat probant puisque j’obtiens une erreur
Code :
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"
Je comprends donc que ce n'est pas encore possible avec MySQL puisqu'il y a la commande LIMIT.
Voilà ma requête :
Code :
1
2
SELECT * FROM categorie
WHERE id_categorie IN (SELECT DISTINCT id_categorie FROM appartenir ORDER BY id_photo DESC LIMIT 0,3)
Comment puis-je donc arriver à ce que je souhaite vraiment ??
Je sèche arrivé à ce stade en ayant essayé des commandes telles que LEFT JOIN, INNER JOIN, EXISTS, ON.... bref j'ai besoin d'aide !!!

Vous remerciant d'avance pour votre précieuse aide.
sebphp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2011, 17h57   #2
Membre habitué
 
Avatar de tfc3146
 
Homme Robert Labrousse
Développeur décisionnel
Inscription : février 2009
Messages : 79
Détails du profil
Informations personnelles :
Nom : Homme Robert Labrousse
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : Boutique - Magasin

Informations forums :
Inscription : février 2009
Messages : 79
Points : 134
Points : 134
Bonjour,
Pouvez-vous nous montrer ce que vous écrivez avec une simple jointure sur la table CATEGORIE. Si vous arrivez à afficher l'identifiant clé, il n'y a pas de raison que vous n'arriviez pas à jointer.

Voici ce que intuitivement j'écrirais mais peut-être l'avez-vous déjà testée :

Code :
1
2
3
4
5
 
SELECT DISTINCT id_categorie, intitule_categorie
FROM categorie
JOIN appartenir ON categorie.id_categorie=appartenir.id_categorie
ORDER BY id_photo DESC LIMIT 0,3
tfc3146 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 04/06/2011, 18h28   #3
Invité de passage
 
Sébastien Perso
Inscription : octobre 2010
Messages : 13
Détails du profil
Informations personnelles :
Nom : Sébastien Perso

Informations forums :
Inscription : octobre 2010
Messages : 13
Points : 2
Points : 2
Merci d'abord pour votre rapidité dans la réponse

Pour faire plus simple lors de l'explication du problème j'avais pris des valeurs d'exemples.. mais le résultat reste le même.

Voilà précisément le script SQL avec la structure et contenance des tables citées.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
-- phpMyAdmin SQL Dump
-- version 3.3.9.2
-- http://www.phpmyadmin.net
--
-- Serveur: 127.0.0.1
-- Généré le : Sam 04 Juin 2011 à 18:18
-- Version du serveur: 5.5.10
-- Version de PHP: 5.3.6
 
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
 
--
-- Base de données: `albumsphotos`
--
 
-- --------------------------------------------------------
 
--
-- Structure de la table `appartenir`
--
 
CREATE TABLE IF NOT EXISTS `appartenir` (
  `id_photo` smallint(6) UNSIGNED NOT NULL,
  `id_categorie` tinyint(3) UNSIGNED NOT NULL,
  PRIMARY KEY (`id_photo`,`id_categorie`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
--
-- Contenu de la table `appartenir`
--
 
INSERT INTO `appartenir` (`id_photo`, `id_categorie`) VALUES
(12, 1),
(13, 5),
(14, 15),
(15, 15),
(16, 2),
(17, 3),
(18, 4),
(19, 4),
(20, 3),
(21, 14),
(22, 10),
(23, 3),
(24, 4),
(25, 5),
(26, 6),
(27, 7),
(28, 8),
(29, 9),
(30, 1),
(98, 2),
(177, 4),
(1558, 2),
(2258, 3),
(2558, 1),
(2558, 8),
(2569, 1),
(4578, 4),
(12589, 2),
(21558, 8),
(22565, 5),
(25448, 4),
(25584, 4),
(25885, 4),
(45869, 7),
(65535, 3),
(65535, 5);
 
-- --------------------------------------------------------
 
--
-- Structure de la table `categorie`
--
 
CREATE TABLE IF NOT EXISTS `categorie` (
  `id_categorie` tinyint(3) UNSIGNED NOT NULL AUTO_INCREMENT,
  `intitule_categorie` char(20) NOT NULL,
  PRIMARY KEY (`id_categorie`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
 
--
-- Contenu de la table `categorie`
--
 
INSERT INTO `categorie` (`id_categorie`, `intitule_categorie`) VALUES
(1, 'Faune & Flore'),
(2, 'Famille'),
(3, 'Voyages'),
(4, 'Sports'),
(5, 'Monuments'),
(6, 'Lieux insolites'),
(7, 'Montages'),
(8, 'Lumières'),
(9, 'Pause longue'),
(10, 'Evènements'),
(11, 'Feux d''artifices'),
(12, 'Nature'),
(13, 'Animaux'),
(14, 'Voitures'),
(15, 'Insolites');
 
-- --------------------------------------------------------
 
--
-- Structure de la table `photo`
--
 
CREATE TABLE IF NOT EXISTS `photo` (
  `id_photo` smallint(6) UNSIGNED NOT NULL,
  `nom_photo` char(20) NOT NULL,
  `repertoire_parent` char(40) NOT NULL,
  `descriptif_photo` varchar(100) DEFAULT NULL,
  `date_photo` date DEFAULT NULL,
  `heure_photo` time DEFAULT NULL,
  `hauteur_photo` smallint(5) NOT NULL,
  `largeur_photo` smallint(5) NOT NULL,
  `orientation_photo` tinyint(1) DEFAULT NULL,
  `note_photo` tinyint(1) DEFAULT NULL,
  `programme_photo` char(1) DEFAULT NULL,
  `vitesse_photo` smallint(3) DEFAULT NULL,
  `ouverture_photo` tinyint(2) DEFAULT NULL,
  `focale_photo` smallint(3) DEFAULT NULL,
  `iso_photo` tinyint(4) DEFAULT NULL,
  `flash_photo` tinyint(1) DEFAULT NULL,
  `balance_photo` char(5) DEFAULT NULL,
  `raw_photo` tinyint(1) NOT NULL,
  `dpp_photo` tinyint(1) NOT NULL,
  `psd_photo` tinyint(1) NOT NULL,
  `id_lieu` smallint(4) NOT NULL,
  `id_boitier` tinyint(2) NOT NULL,
  PRIMARY KEY (`id_photo`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Pour le moment je n'ai pas encore écrit le code PHP pour insérer chaque enregistrement dans les tables concernées.
C'était juste un test sur PhpMyAdmin pour visualiser le résultat des requêtes.
Toutefois, celui ci ressemblerait à ceci :
Boucle tant qu'il y a de catégories cochées pour insérer dans la table appartenir l'ID de la photo en question, et l'ID de la catégorie concernée.
Évidemment, il y aurait autant d'enregistrements que de catégories sélectionnées.

Quant à la requête proposée, je pense l'avoir déjà testée puisque je me suis retrouvé avec le même résultat à un moment donné.
Requête testée à l'instant avec ma base de données
Le résultat est le suivant... :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
"9";"Pause longue"
"8";"Lumières"
"7";"Montages"
"6";"Lieux insolites"
"10";"Evènements"
"14";"Voitures"
"4";"Sports"
"3";"Voyages"
"2";"Famille"
"15";"Insolites"
"5";"Monuments"
"1";"Faune & Flore"
...alors que le résultat devrait être celui-ci. Jusqu'à maintenant j'arrive à récupérer que les ID des catégories, le LIMIT n'est pas mis dans le résultat :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
"5"
"3"
"7"
"4"
"8"
"2"
"1"
"9"
"6"
"10"
"14"
"15"
Avez-vous une autre hypothèse ?
Merci d'avance !
sebphp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2011, 18h31   #4
Membre confirmé
 
Homme
Développeur informatique
Inscription : avril 2011
Messages : 196
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Italie

Informations professionnelles :
Activité : Développeur informatique
Secteur : Transports

Informations forums :
Inscription : avril 2011
Messages : 196
Points : 298
Points : 298
Moi je propose ceci :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT B.id_categorie, intitule_categorie
FROM
(
SELECT DISTINCT A.id_categorie
FROM
(
SELECT id_categorie, id_photo
FROM appartenir 
ORDER BY id_photo DESC
) A
LIMIT 0,3
) B
INNER JOIN categorie C ON C.id_categorie=B.id_categorie
Testé sur les deux jeux de données fournis, pour le premier ca donne :
Code :
1
2
3
1  Faune & Flore
2 Voyages 
5 Sports
et pour le deuxieme :
Code :
1
2
3
5 	Monuments
3 	Voyages
7 	Montages
fab256 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 04/06/2011, 18h45   #5
Invité de passage
 
Sébastien Perso
Inscription : octobre 2010
Messages : 13
Détails du profil
Informations personnelles :
Nom : Sébastien Perso

Informations forums :
Inscription : octobre 2010
Messages : 13
Points : 2
Points : 2
Génial cela fonctionne !!

Merci beaucoup pour votre aide !!

Je ne savais même pas que l'on pouvait faire des sous requêtes dans une clause FROM, j'ai encore appris une chose

Par contre pour complexifier un peu la chose j'aurai voulu savoir si je pouvais avoir en un seul résultat :
Dans l'ordre, les 3 dernières catégories utilisées classées par ordre alphabétique, puis les autres restantes classées elles aussi dans l'ordre alphabétique ?

Ou faut-il que je scinde en 2 requêtes bien distinctes ?

J'ai déjà un élément de réponse avec
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT B.id_categorie, intitule_categorie
FROM (
 
SELECT DISTINCT A.id_categorie
FROM (
 
SELECT id_categorie, id_photo
FROM appartenir
ORDER BY id_photo DESC
)A
LIMIT 3 , 999
)B
INNER JOIN categorie C ON C.id_categorie = B.id_categorie
ORDER BY intitule_categorie ASC
qui me donne le résultat suivant
Code :
1
2
3
4
5
6
7
8
9
"10";"Evènements"
"2";"Famille"
"1";"Faune & Flore"
"15";"Insolites"
"6";"Lieux insolites"
"8";"Lumières"
"9";"Pause longue"
"4";"Sports"
"14";"Voitures"
Possible ou pas de faire tout ça en une seule ?
Merci d'avance !
sebphp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2011, 22h59   #6
Membre confirmé
 
Homme
Développeur informatique
Inscription : avril 2011
Messages : 196
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Italie

Informations professionnelles :
Activité : Développeur informatique
Secteur : Transports

Informations forums :
Inscription : avril 2011
Messages : 196
Points : 298
Points : 298
Ça m’étonnerait que tu puisses faire ce que tu veux en une seule requête, à la limite tu peux faire UNION entre tes deux requêtes.
fab256 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 12h34   #7
Invité de passage
 
Sébastien Perso
Inscription : octobre 2010
Messages : 13
Détails du profil
Informations personnelles :
Nom : Sébastien Perso

Informations forums :
Inscription : octobre 2010
Messages : 13
Points : 2
Points : 2
Merci encore Fabien pour ton aide !!
Je me suis résolu à faire deux requêtes distinctes pour mon script PHP.

Par contre, pour finir j'ai encore un petit soucis. La requête suivante me donne les autres catégories de la table appartenir.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT TableB.id_categorie, intitule_categorie
FROM (
 
SELECT DISTINCT TableA.id_categorie
FROM (
 
SELECT id_categorie, id_photo
FROM appartenir
ORDER BY id_photo DESC
)TableA
LIMIT 3 , 9999
)TableB
INNER JOIN categorie TableC ON TableC.id_categorie = TableB.id_categorie
Le problème est qu'il me reste 3 autres catégories encore jamais utilisées qui ne sont donc pas dans la table appartenir. (catégories n°11, 12, 13)

J'ai testé la requête
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT TableB.id_categorie
FROM (
 
SELECT DISTINCT TableA.id_categorie
FROM (
 
SELECT id_categorie, id_photo
FROM appartenir
ORDER BY id_photo DESC
)TableA
LIMIT 4 , 8888
)TableB
 
UNION
 
SELECT id_categorie
FROM `categorie`
mais celle-ci me retourne en plus les catégories dernièrement utilisées.
Comment pourrais-je avoir seulement les 3 autres restantes ?
J'ai testé la commande WHERE id_categorie IN mais cela me ressort une erreur. Probablement puisque la colonne est nommée, et n'est pas une suite de valeurs uniquement.

Une idée ?
Merci d'avance pour vos réponses !
sebphp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 16h45   #8
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 006
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 006
Points : 18 276
Points : 18 276
Envoyer un message via MSN à CinePhil
Peut-être que les solutions qu'on t'a proposées semblent fonctionner mais je doute !
Citation:
Dans l'ordre, les 3 dernières catégories utilisées classées par ordre alphabétique, puis les autres restantes classées elles aussi dans l'ordre alphabétique ?
Sur quel critère détermines-tu quelles sont les dernières catégories utilisées ?
Sur la date de la photo ? Sur son identifiant ?
Et si tu affectes après coup une catégorie à une photo déjà enregistrée depuis un certain temps, faut-il considérer cette catégorie comme étant la dernière utilisée ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 16h54   #9
Invité de passage
 
Sébastien Perso
Inscription : octobre 2010
Messages : 13
Détails du profil
Informations personnelles :
Nom : Sébastien Perso

Informations forums :
Inscription : octobre 2010
Messages : 13
Points : 2
Points : 2
Que de bonnes questions CinePhil, auxquelles je n'avais pas vraiment pensé

Pour commencer, j'ai finalement changé d'avis pour la classement des catégories récentes. Celles-ci devront être classées dans l'ordre de leur dernière utilisation. Pour cela, c'est bon, j'ai réussi avec l'aide de Fabien.

Il est vrai que mon premier choix de se baser sur l'ordre des ID des photos de la table appartenir n'est pas stable a priori. Puisque comme tu me l'as fait remarquer, si l'utilisateur ajoute une autre catégorie à une photo déjà référencée, cela ne sera pas bien géré.

Je pense que je vais, au final, devoir ajouter une colonne DateTime dans la table appartenir. De là, je pourrai me baser sur ce critère pour avoir les dernières utilisées.

Merci de m'y avoir fait pensé !
sebphp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 18h05   #10
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 006
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 006
Points : 18 276
Points : 18 276
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par sebphp Voir le message
Pour commencer, j'ai finalement changé d'avis pour la classement des catégories récentes. Celles-ci devront être classées dans l'ordre de leur dernière utilisation.
Donc la question reste posée sur l'aspect "dernière" !

Mais tu y réponds plus loin avec la bonne solution :
Citation:
Je pense que je vais, au final, devoir ajouter une colonne DateTime dans la table appartenir. De là, je pourrai me baser sur ce critère pour avoir les dernières utilisées.
Je n'ai pas regardé en détail mais j'ai l'impression que la requête qu'on t'a proposée est excessivement compliquée.

Regarde cette source pour avoir les trois premiers éléments par catégorie et inspire t'en pour avoir tes trois dernières catégories utilisées.

Bonne chance et poste nous ta requête qu'on voie si on peut l'améliorer.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h41.


 
 
 
 
Partenaires

Hébergement Web