Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
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 10/05/2011, 23h10   #1
Invité de passage
 
Didier
Inscription : mars 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Didier

Informations forums :
Inscription : mars 2011
Messages : 14
Points : 0
Points : 0
Par défaut Sous requete erronée

bonjour,

j'ai 2 requetes qui fonctionnent séparément, je souhaite les mettre en une seule requete, le resultat de la premiere requete select est ok, mais le second est erronée, pouvez vous m'aider, je suppose que ça vient de la syntaxe, surement aussi, vous rendrez plus efficace mon script! suis débutant
merci! le resultat ci dessous de la colonne 6 à 10 répète le meme n° de dde indéfiniment.

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
SELECT *
FROM
(
    (
        SELECT * , DATEDIFF( Date_Valide, Date_A_Valider ) AS Ecart
        FROM
        (
            SELECT Num_demande AS A_Valider, Date_Statut AS Date_A_Valider
            FROM table_statut_demande
            WHERE `Num_Statut` =1
                AND year( `Date_Statut` ) =2011
        )table1, 
        (
            SELECT Num_demande AS Valide, Date_Statut AS Date_Valide
            FROM table_statut_demande
            WHERE Num_statut =2
                AND year( date_statut ) =2011
        )table2
        WHERE A_Valider = Valide
        ORDER BY `Ecart` DESC
    )tableValidee, -------------> resultat ok
    (
        SELECT * , DATEDIFF( Date_Validee, Date_EnCours ) AS Ecart1
        FROM 
        (
            SELECT Num_demande AS DdeValidee, Date_Statut AS Date_Validee
            FROM table_statut_demande
            WHERE `Num_Statut` =2
            AND year( `Date_Statut` ) =2011
        )table3, 
        (
            SELECT Num_demande AS DdeEnCours, Date_Statut AS Date_Encours
            FROM table_statut_demande
            WHERE Num_statut =5
                AND year( date_statut ) =2011
        )table4
        WHERE DdeValidee = DdeEnCours
        ORDER BY `Ecart1` DESC
    )tableEnCours------------------> resultat erroné, mais requete ok si lancé seule
)
le resultat de cette requete:

A_Valider Date_A_Valider Valide Date_Valide Ecart DdeValidee Date_Validee DdeEnCours Date_Encours Ecart1
65678 2011-01-12 65678 2011-04-01 79 66890 2011-03-17 66890 2011-02-03 42
66373 2011-01-24 66373 2011-03-17 52 66890 2011-03-17 66890 2011-02-03 42
65228 2011-01-05 65228 2011-02-08 34 66890 2011-03-17 66890 2011-02-03 42
didier12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 14h28   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 998
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 : 10 998
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Ta requête est un catalogue de ce qu'il ne faut pas faire !

Pour commencer, évite la guerre des étoiles !

Ensuite, les jointures s'écrivent depuis 1992 avec l'opérateur JOIN !

Les sous-requêtes enchaînées de la sorte sont contre-performantes.

Dans tes deux sous-requêtes principales (tableValidee et tableEncours), tu n'as pas de condition de jointure entre les instances de ta table_statut_demande. Du coup, tu fais un produit cartésien entre les deux instances, ce qui te donne nombre de lignes de la table au carré !

Les apostrophes inversées ajoutées par phpMyadmin autour des noms de colonnes et de tables sont généralement inutiles.

Si j'ai bien compris l'ensemble, pour ta première sous-requête :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    (
        SELECT * , DATEDIFF( Date_Valide, Date_A_Valider ) AS Ecart
        FROM
        (
            SELECT Num_demande AS A_Valider, Date_Statut AS Date_A_Valider
            FROM table_statut_demande
            WHERE `Num_Statut` =1
                AND year( `Date_Statut` ) =2011
        )table1, 
        (
            SELECT Num_demande AS Valide, Date_Statut AS Date_Valide
            FROM table_statut_demande
            WHERE Num_statut =2
                AND year( date_statut ) =2011
        )table2
        WHERE A_Valider = Valide
        ORDER BY `Ecart` DESC
    )tableValidee
Tu dois pouvoir l'écrire comme ceci :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT d1.Num_demande, 
    d1.Date_Statut AS Date_A_Valider,
    d2.Date_Statut AS Date_Valide,
    DATEDIFF( d2.Date_Statut, d1.Date_Statut ) AS Ecart
FROM table_statut_demande d1
INNER JOIN table_statut_demande d2 
    ON d2.Num_demande = d1.Num_demande
    AND d1.A_Valider = d2.Valide
WHERE d1.Num_Statut = 1
    AND YEAR( d1.Date_Statut ) = 2011
    AND d2.Num_Statut = 2
    AND YEAR( d2.Date_Statut ) = 2011
ORDER BY DATEDIFF( d2.Date_Statut, d1.Date_Statut ) DESC
Tu peux t'en inspirer pour intégrer l'autre partie.

Je comprends mal l'utilité des colonnes A_Valider et Valide puisque cela doit être indiqué par Num_Statut non ?

La structure de la table et une explication de ce qu'est censée faire cette requête nous aiderait à la comprendre.
__________________
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 déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 20h04   #3
Invité de passage
 
Didier
Inscription : mars 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Didier

Informations forums :
Inscription : mars 2011
Messages : 14
Points : 0
Points : 0
Par défaut merci pour votre aide précieuse! j'ai encore le probleme

je me doutais bien que ma requete n'etait pas conforme, mais j'apprends

j'ai donc rajouter la deuxieme à la premiere, mais le resultat est identique au precedent, il me sors x fois les memes enregistrements!

Le but de ces requetes est de mesurer l'ecart de date entre les differents statuts correspondants à des demandes de travaux Num_demande est le numero de la demande, num_statut = 1 >A_Valider, =2 Validé, =5 En cours.
j'affiche les colonnes des dates afin de controler la véracité des résultats.

j'aimerais aussi séparer par une colonne vide,ici 'Motif' les colonnes de la premiere requete avec celles de la deuxieme.

Voici la requete que j'ai tentée:
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
SELECT * 
FROM (
(
 
SELECT d1.Num_demande, d1.Date_Statut AS Date_A_Valider, d2.Date_Statut AS Date_Valide, DATEDIFF( d2.Date_Statut, d1.Date_Statut ) AS Ecart, d1.Motif
FROM table_statut_demande d1
INNER JOIN table_statut_demande d2 ON d2.Num_demande = d1.Num_demande
WHERE d1.Num_Statut =1
AND YEAR( d1.Date_Statut ) =2011
AND d2.Num_Statut =2
AND YEAR( d2.Date_Statut ) =2011
ORDER BY DATEDIFF( d2.Date_Statut, d1.Date_Statut ) DESC 
)tableAvalider, (
 
SELECT d3.Num_demande, d3.Date_Statut AS Date_Encours, d4.Date_Statut AS Date_Validee, DATEDIFF( d4.Date_Statut, d3.Date_Statut ) AS Ecart2, d3.Motif
FROM table_statut_demande d3
INNER JOIN table_statut_demande d4 ON d4.Num_demande = d3.Num_demande
WHERE d3.Num_Statut =5
AND YEAR( d3.Date_Statut ) =2011
AND d4.Num_Statut =2
AND YEAR( d4.Date_Statut ) =2011
ORDER BY DATEDIFF( d4.Date_Statut, d3.Date_Statut ) DESC 
)tableEncours
)
*******************************************************
et voici le resultat toujours erroné pour la seconde:

Num_demande Date_A_Valider Date_Valide Ecart Motif Num_demande Date_Encours Date_Validee Ecart2 Motif
65678 2011-01-12 2011-04-01 79 NULL 66890 2011-02-03 2011-03-17 42 NULL
66373 2011-01-24 2011-03-17 52 NULL 66890 2011-02-03 2011-03-17 42 NULL
65228 2011-01-05 2011-02-08 34 NULL 66890 2011-02-03 2011-03-17 42 NULL
*********************************************************
merci encore pour votre aide
didier12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 00h17   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 998
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 : 10 998
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Apparemment, tu n'es pas allé lire l'article sur les jointures !

Pas le temps à cette heure de développer.
__________________
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 déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 10h11   #5
Invité de passage
 
Didier
Inscription : mars 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Didier

Informations forums :
Inscription : mars 2011
Messages : 14
Points : 0
Points : 0
Par défaut JOINTURE

j'ai bien lu les infos sur les jointures, je les comprends bien quand il s'agit de plusieurs tables, mais lorsqu'on extrait les infos d'une meme table, pas si évident. Doit on considérer qu'on fait la meme chose que s'il y en vait plusieurs donc en disant que :
table_statut_demande d1
INNER JOIN table_statut_demande d2
INNER JOIN table_statut_demande d3

je vais y travailler, pouvez vous me dire aussi si on peut mettre un timeout sur la requete afin de limiter le temps de calcul sur le serveur, car lors de mes essais, j'arrive à le planter , donc je ne travaille que le soir apres les heures, si je pouvais mettre un timeout de 10s, ça serait cool
merci
didier12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 10h41   #6
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 998
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 : 10 998
Points : 18 262
Points : 18 262
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par didier12 Voir le message
j'ai bien lu les infos sur les jointures, je les comprends bien quand il s'agit de plusieurs tables, mais lorsqu'on extrait les infos d'une meme table, pas si évident. Doit on considérer qu'on fait la meme chose que s'il y en vait plusieurs donc en disant que :
table_statut_demande d1
INNER JOIN table_statut_demande d2
INNER JOIN table_statut_demande d3
Oui. Si tu as besoin de joindre une table avec elle même, tu en génères plusieurs instances. C'est d'ailleurs ce que j'ai fait dans ma requête :
Code :
1
2
FROM table_statut_demande d1
INNER JOIN table_statut_demande d2
Il fallait donc continuer.

Citation:
j'ai donc rajouter la deuxieme à la premiere, mais le resultat est identique au precedent, il me sors x fois les memes enregistrements!
C'est parce que tu n'as pas de condition de jointure entre tes deux sous-requêtes donc tu te retrouves avec un produit cartésien du résultat des deux sous-requêtes.

Si j'ai correctement interprété ta requête, regarde si cette forme convient :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SELECT d1.Num_demande, 
    d1.Date_Statut AS Date_A_Valider,
    d2.Date_Statut AS Date_Valide,
    d3.Date_Statut AS Date_Encours, 
    DATEDIFF( d2.Date_Statut, d1.Date_Statut ) AS Ecart_Validation, 
    d1.Motif AS Motif_Validation,
    DATEDIFF( d2.Date_Statut, d3.Date_Statut ) AS Ecart_En_Cours,
    d3.Motif AS Motif_En_Cours
FROM table_statut_demande d1
INNER JOIN table_statut_demande d2 ON d2.Num_demande = d1.Num_demande
INNER JOIN table_statut_demande d3 ON d3.Num_demande = d1.Num_demande
WHERE d1.Num_Statut = 1
    AND YEAR( d1.Date_Statut ) = 2011
    AND d2.Num_Statut = 2
    AND YEAR( d2.Date_Statut ) = 2011
    AND d3.Num_Statut = 5
    AND YEAR( d3.Date_Statut ) = 2011
ORDER BY DATEDIFF( d2.Date_Statut, d1.Date_Statut ) DESC
Citation:
je vais y travailler, pouvez vous me dire aussi si on peut mettre un timeout sur la requete afin de limiter le temps de calcul sur le serveur, car lors de mes essais, j'arrive à le planter , donc je ne travaille que le soir apres les heures, si je pouvais mettre un timeout de 10s, ça serait cool
merci
Si tu as des problèmes de lenteur de requête, commence par vérifier que ta table est correctement indexé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 déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 13h45   #7
Invité de passage
 
Didier
Inscription : mars 2011
Messages : 14
Détails du profil
Informations personnelles :
Nom : Didier

Informations forums :
Inscription : mars 2011
Messages : 14
Points : 0
Points : 0
Par défaut suite

j'avais commencé à ajouter la deuxieme requete, mais vous avez été plus rapide que moi !
je l'ai donc lancée, mais le resultat attendu ne correspond pas à mes besoins. En fait j'avais travaillé en sous requete pour essayer de sortir 2 tableaux l'un pour mesurer les ecarts entre les dates a valider-validée selon statut=1 et 2
puis le seconde pour les ecarts entre date validée et encours, statut= 2 et 5

Le but serait de sortir les resultats sur une seule requete au lieu de lancer les 2 separements (j'en ai une 3eme à rajouter) afin d'exporter le resultat en CSV;mais peut etre on ne peut pas realiser ce dont j'ai besoin:

quand je lance la premiere requete seule, je trouve 141 enregistrements
quand je lance la deuxieme seule, il y en a 573
si je compile les deux en copiant collant votre modif, en fait on filtre les resultats sur les deux requetes au lieu de les retrouver avec chacune le nombre d'enregistrements souhaitées, je ne trouve plus que 95 enregistrements
didier12 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h46.


 
 
 
 
Partenaires

Hébergement Web