IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Requête casse tête


Sujet :

Requêtes MySQL

  1. #1
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut Requête casse tête
    Hello,

    J'ai une "table1" qui contient des infos telles que le statut et l'id
    J'ai une "table2" qui permet d'enregistrer l'historique des modifications apportées à "table1". "table2" contient les champs table1Id, date, newStatus, OldStatus.

    Je souhaiterais faire une requête qui va me grouper tous les enregistrements de table1 dont le statut=9 et dont "table2" contient au moins une fois un historique avec "newStatus=9" et "oldStatus=7". Cependant, comme c'est un historique, il y a plusieurs enregistrement identique, car on peut annuler une action et la refaire par la suite hors, dans mon count(*), ca reprend le nombre de fois que l'on trouve un enregistrement dans "table2" correspondant aux critères. Hors ce n'est pas mon cas ici. Je m'en fou de tous les enregistrements de "table2", je veux juste le plus récent qui correspond au critère.

    Voici la requête vous comprendrez peut être mieux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT COUNT(*) AS nb, DATE(t2.date) AS date
     FROM table1 AS t1 
    INNER JOIN table2 as t2 ON t2.table1Id=t1.id 
    WHERE t1.statusId=9 
    AND (DATE(t2.date) BETWEEN "2011-01-01" AND "2012-01-01" ) 
    AND t2.newStatus=9 
    AND t2.oldStatus=7 
    GROUP BY MONTH(t2.date)  
    ORDER BY t2.date DESC
    Cette requête devrait normalement me retourner 2 enregistrements mais elle m'en retourne 6 car j'ai 5x la correspondance dans la table2 pour un enregistrement, hors j'aimerais juste prendre 1 seul enregistrement unique et le dernier de la table2 pour faire la jointure avec la table1.

    Une idée?

    Merci beaucoup

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Ceci :
    dont "table2" contient au moins une fois
    se traduit en SQL par cela :
    Mais vu votre requête et ce que vous dîtes plus loin, j'ai des doutes sur la formulation de votre besoin :
    Je souhaiterais faire une requête qui va me grouper tous les enregistrements de table1
    ...
    Je m'en fous de tous les enregistrements de "table2", je veux juste le plus récent qui correspond au critère.
    Vous voulez les lignes de t1 ou de t2 ?

    En plus, votre requête est fausse !
    Puisque vous groupez par MONTH(t2.date), vous devriez avoir MONTH(t2.date) dans le SELECT et non pas date.
    Quelle date le SGBD va t-il choisir pour le mois de janvier ?
    Le '2011-01-14', le '2012-01-01' ?

    Au passage, 'date' est un mauvais nom de colonne car c'est un mot réservé du langage SQL.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « 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 la suite Linux Mageïa !

  3. #3
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Bonjour,

    Oui date n'est pas mon nom de champ, c'était pour l'exemple ici.

    Je reformule ce que je souhaiterais faire.

    Je dois récupérer par groupement MONTH(t2.date) les enregistrements de t1.

    MAIS, je dois prendre uniquement dans t2 la date la plus récente des enregistrements qui "match" t2.newStatus=9 AND t2.oldStatus=7. Cela permet de me trouver la date à laquelle t1 a changé de statut.

    Or, sur un enregistrement, j'ai parfois 5 correspondances, mais il ne me faut que la plus récente.

    Entre le BETWEEN, je me suis trompé, il faut bien sûr imaginer deux dates différentes sinon ça n'a pas de sens

    Ce que je veux faire au final, c'est compter le nombre d'ID de t1 ayant la correspondance la plus récente dans t2 groupé par MONTH(t2.date).

    Est-ce plus clair?

  4. #4
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    En fait je pense que je peux faire ça avec des requêtes imbriquées...

  5. #5
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Voilà j'ai finalement réglé mon problème en une requête, j'ai simplement fait un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    COUNT(DISTINCT t2.table1Id) as nb

  6. #6
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Je me suis trompé, ça n'a pas réglé mon problème...

    Voici le résultat sans le count et le group by:

    2012-11-08 4260
    2012-11-08 4249
    2012-11-08 4248
    2012-11-08 4205
    2012-11-08 4193
    2012-11-08 12
    2012-11-08 4260
    2012-11-08 4260
    2012-08-20 4248
    2012-02-16 4249
    2012-02-16 4249
    2012-02-16 4249
    2012-02-16 4249
    2012-02-16 4249


    A gauche la date contenu dans t2, à droite l'ID de t1. Je souhaiterais un COUNT sur l'ID de t1. Normalement ca devrait retourner 6 au total.

    Normalement la requête ne devrait prendre en considération uniquement ceux-ci:

    2012-11-08 4260
    2012-11-08 4249
    2012-11-08 4248
    2012-11-08 4205
    2012-11-08 4193
    2012-11-08 12

    et donc en bref, je souhaiterais un group by date et un count par date ce qui donnerait:

    2012-11-08 et 6 pour le count.

    Comment puis-je corriger cela?

    Merci.

    Voici la requête sans le count et le group by:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT DATE( t2.date ) AS saleDate, t1.id
    FROM table1 AS t1
    INNER JOIN table AS t2 ON t2.carId = t1.id
    WHERE t1.deleted =0
    AND t1.type =1
    AND t1.statusId =9
    AND (
    DATE( t2.date ) 
    BETWEEN  "2011-01-01"
    AND  "2012-11-08"
    )
    AND t2.statusId =9
    AND t2.statusOldId =7
    ORDER BY t2.date DESC
    J'aimerais donc ajouter à cette requête un COUNT et un GROUP BY afin d'obtenir ceci:

    2012-11-08 et 6 de count

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Pas sûr d'avoir tout compris encore...

    La requête ci-dessous donne, pour chaque table1id d'ancien statut 7 et de nouveau statut 9 et compris entre le 01/01/2011 et 01/01/2012 (inclus !) la date la plus récente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT table1Id,
    	MAX(DATE(`date`) AS derniere_date
    FROM table2
    WHERE newStatus = 9
    	AND oldStatus = 7
    	AND DATE(`date`) BETWEEN '2011-01-01' AND '2012-01-01'
    GROUP BY table1Id
    La requête suivante compte le résultat de la requête précédente par date :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT tmp.derniere_date, COUNT(*) AS nombre
    FROM
    (
    	SELECT table1Id,
    		MAX(DATE(`date`) AS derniere_date
    	FROM table2
    	WHERE newStatus = 9
    		AND oldStatus = 7
    		AND DATE(`date`) BETWEEN '2011-01-01' AND '2012-01-01'
    	GROUP BY table1Id
    ) tmp
    GROUP BY tmp.derniere_date
    C'est ça que tu veux ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « 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 la suite Linux Mageïa !

  8. #8
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Ça m'a tout l'air d'être ça!

    Je teste et je dis quoi!

  9. #9
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête (casse tête)
    Par shadeoner dans le forum Requêtes
    Réponses: 2
    Dernier message: 13/02/2008, 10h35
  2. Requête casse tête.. à vous de jouer.. :)
    Par chriscoolletoubibe dans le forum Hibernate
    Réponses: 3
    Dernier message: 17/09/2007, 09h39
  3. requête casse-tête pour une seule table..
    Par MikeV dans le forum Requêtes
    Réponses: 9
    Dernier message: 23/08/2007, 21h02
  4. Requête (casse tête)
    Par shadeoner dans le forum SQL
    Réponses: 13
    Dernier message: 12/06/2007, 17h13
  5. Requête casse tête!
    Par sonorc dans le forum Langage SQL
    Réponses: 10
    Dernier message: 08/05/2007, 02h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo