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 :

Pb classement avec ORDER BY ?


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Touriste en programmation
    Inscrit en
    Janvier 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Touriste en programmation
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 49
    Par défaut Pb classement avec ORDER BY ?
    Bonsoir,

    Je suis en train de m'arracher les cheveux sur une requête que je n'arrive pas à écrire... Probablement une histoire de requête imbriquée, mais je ne trouve pas.

    Il s'agit d'un suivi de conseils de prise en charge (domaine médical), dans lequel je note les avis formulés. Avis une première fois, suite d'avis, puis 3e question toujours pour la même histoire, etc. En sachant que les coups de fils s'enchainent, passent d'un nouveau patient à une ancienne histoire, puis re-le nouveau patient, puis encore un nouveau, puis retour sur un ancien, etc...

    Ma table cmi_cmi est construite ainsi :

    - numcmi : identifiant unique de chaque avis
    - numcmiref : avis initial auquel se rapporte l'avis numcmi (pour un premier avis sur un problème, numcmiref = numcmi. Pour les avis suivants, numcmiref renvoie au premier avis formulé pour le patient en question)
    - datecmi
    - contenu, etc.


    Dans la page de consultation des avis formulés, je voudrais afficher entre une date A et une date B tous les avis formulés, mais aussi tout leur historique (= pour chaque avis formulé entre A et B, afficher aussi les avis antérieurs à la date A concernant le même patient = ayant le même numcmiref)

    Pour plus de lisibilité, je "packe" les avis liés à un même patient.
    Jusque là, j'y arrive.

    Mais ce que je n'arrive pas à faire, c'est à ordonner les "packs" par ordre croissant de date d'avis le plus récent (par MAX(datecmi) de chaque numcmiref, quoi)

    J'ai essayé des trucs du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $q1="SELECT DISTINCT numcmiref 
    FROM cmi_cmi 
    INNER JOIN 
    (
      SELECT numcmiref, MAX(datecmi) AS datecmi 
      FROM cmi_cmi 
      WHERE datecmi BETWEEN '".$dateA."' AND '".$dateB."' 
      GROUP BY numcmiref
    ) AS sousrequete USING(numcmiref, datecmi)";
    puis une boucle sur les différents numcmiref pour récupérer pour chacun tous les avis (numcmi) dans l'ordre chronologie et les afficher en pack

    Mais l'ordre chronologique entre les packs n'est pas strictement respecté : c'est plutôt pas mal, mais certains avis ne sont pas à leur place (sans que j'arrive à définir de règle)

    J'ai essayé aussi divers ORDER BY, sans succès

    Je ne sais pas si mon problème est bien clair...

    Merci déjà à ceux qui ont eu la patience de me lire jusque là !

    BM

  2. #2
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Cette requête ne répondrait-elle pas au besoin ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT c1.numcmi AS antecedent,
    	c1.datecmi AS date_antecedent,
    	tmp.numcmi AS avis,
    	tmp.datecmi AS date_avis
    FROM 
    (
    	SELECT numcmi, datecmi
    	FROM cmi_cmi
    	WHERE datecmi BETWEEN '".$dateA."' AND '".$dateB."'
    ) tmp
    INNER JOIN cmi_cmi c1 ON c1.numcmiref = tmp.numcmi
    ORDER BY c1.datecmi, tmp.datecmi
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 averti
    Homme Profil pro
    Touriste en programmation
    Inscrit en
    Janvier 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Touriste en programmation
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 49
    Par défaut
    Merci pour ta réponse rapide

    J'essaie de comprendre ta requête et de voir si ça marche et répond à ma question, je te redis bien vite

  4. #4
    Membre averti
    Homme Profil pro
    Touriste en programmation
    Inscrit en
    Janvier 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Touriste en programmation
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 49
    Par défaut
    De ce que je comprends de ta requête, elle ne sélectionne que les avis qui ont débuté dans la période [A-B] (INNER JOIN cmi_cmi c1 ON c1.numcmiref = tmp.numcmi)

    Hors moi, je voudrais tous les avis qui ont été formulés pendant [A-B], même si l'avis initial était antérieur à A.
    On serait donc plutôt sur un (INNER JOIN cmi_cmi c1 ON c1.numcmiref = tmp.numcmiref) : jointure sur tous les avis qui ont le même message initial (numcmiref) que ceux formulés pendant [A-B]

    Mais en faisant ça, les avis ne sont toujours pas ordonnés comme je le voudrais...

    Voilà où en est ma requête actuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT tout.numcmi AS tout_numcmi, tout.numcmiref AS tout_numcmiref,
    		tout.datecmi AS tout_datecmi, tout.resumecmi AS tout_resumecmi, 
    		periode.numcmi AS numcmi_periode, periode.datecmi AS datecmi_periode
    			FROM 
    			(
    				SELECT numcmi, numcmiref, datecmi
    				FROM cmi_cmi
    				WHERE datecmi BETWEEN '".$datedeb."' AND '".$datefin."'
    			) periode
    	INNER JOIN cmi_cmi tout ON tout.numcmiref = periode.numcmiref
    	ORDER BY periode.datecmi, tout.datecmi
    Et voilà en guise d'exemple ce qu'elle donne :
    ...
    1612 (réf 1603) le 2012-07-18

    1608 (réf 1608) le 2012-07-17

    1474 (réf 1474) le 2012-06-01

    1603 (réf 1603) le 2012-07-16

    1611 (réf 1474) le 2012-07-18

    1609 (réf 1609) le 2012-07-18

    1612 (réf 1603) le 2012-07-18

    1613 (réf 1613) le 2012-07-18
    ...
    Pas dans l'ordre, et des doublons. Mais ça me donne des pistes de réflexion, je vais y retravailler.

    Le plus simple serait surement déjà de sélectionner les sujets (numcmiref) de la période [A-B] (facile) ordonnés selon le datecmi le plus élevé pour chaque numcmiref (moins facile...).
    Ce qui ferait ici pour mon exemple :
    1608
    1474
    1603
    1609
    1613
    Par la suite, il sera facile avec une boucle de passer les numcmiref en revue, et d'afficher pour chacun l'ensemble des avis (numcmi) groupés et triés par ordre chronologique.

  5. #5
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Je crois en effet que j'ai mis ma jointure à l'envers.

    Mon but était de sélectionner les numcmi entre les dates puis de faire la jointure pour trouver leurs antécédants mais j'ai inversé la condition de jointure.
    Ceci devrait mieux fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT c1.numcmi AS antecedent,
    	c1.datecmi AS date_antecedent,
    	tmp.numcmi AS avis,
    	tmp.datecmi AS date_avis
    FROM 
    (
    	SELECT numcmi, datecmi
    	FROM cmi_cmi
    	WHERE datecmi BETWEEN '".$dateA."' AND '".$dateB."'
    ) tmp
    INNER JOIN cmi_cmi c1 ON tmp.numcmiref = c1.numcmi
    ORDER BY c1.datecmi, tmp.datecmi
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

  6. #6
    Membre averti
    Homme Profil pro
    Touriste en programmation
    Inscrit en
    Janvier 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Touriste en programmation
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 49
    Par défaut
    Merci, je comprends mieux la "philosophie" de ta requête.

    Mais pour un avis de la période, il peut y avoir plusieurs "antécédents" (par exemple les numcmi 12, 16, 27, 32, ayant tous pour numcmiref la valeur 12), alors que si je comprends bien ta jointure, elle ne permet de trouver que le tout premier, celui dont numcmi=numcmiref (numcmi 12 dans mon exemple)

    La requête suivante donne presque le résultat voulu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT c1.numcmi AS c1_numcmi, c1.numcmiref AS c1_numcmiref, c1.datecmi AS c1_datecmi 
    			FROM 
    			(
    				SELECT numcmiref, datecmi
    				FROM cmi_cmi
    				WHERE datecmi BETWEEN '".$datedeb."' AND '".$datefin."'
    			) tmp
    	INNER JOIN cmi_cmi c1 ON c1.numcmi = tmp.numcmiref
    	ORDER BY tmp.datecmi
    Le seul problème qu'il me reste, c'est que si N avis sont donnés dans la période pour un même numcmiref, je vais avoir le "pack" correspondant en N exemplaires au lieu d'un seul.

    Mais si je place un "GROUP BY numcmiref" ou un "DISTINCT numcmiref", c'est le datecmi le plus ancien qui va être gardé pour chaque numcmiref, et non le plus récent, alors les packs ne seront pas classés dans l'ordre voulu. Et je me retrouve au point de départ... (J'avais pensé me servir d'un "MAX()", mais je ne vois pas comment)

    AAAAAAAAAAArrrrrrrrgggggggggghhhhhhhhhhhhh !!!!!!!!!!!

  7. #7
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Je reprends du besoin de départ...

    je voudrais afficher entre une date A et une date B tous les avis formulés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT numcmi
    FROM cmi_cmi
    WHERE datecmi BETWEEN '".$dateA."' AND '".$dateB."'
    mais aussi tout leur historique (= pour chaque avis formulé entre A et B, afficher aussi les avis antérieurs à la date A concernant le même patient = ayant le même numcmiref)
    La requête que j'ai proposée au message #5 récupère l'antécédent des numcmi compris entre deux dates. Je la corrige cependant car il manquait numcmiref dans la sous-requête :
    Citation Envoyé par CinéPhil
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT c1.numcmi AS antecedent,
    	c1.datecmi AS date_antecedent,
    	tmp.numcmi AS avis,
    	tmp.datecmi AS date_avis
    FROM 
    (
    	SELECT numcmi, datecmi, numcmiref
    	FROM cmi_cmi
    	WHERE datecmi BETWEEN '".$dateA."' AND '".$dateB."'
    ) tmp
    INNER JOIN cmi_cmi c1 ON tmp.numcmiref = c1.numcmi
    ORDER BY c1.datecmi, tmp.datecmi
    Maintenant, tu veux tous les numcmi descendants des numcmi d'origine. La requête de mon message #7 donne cette liste complète (elle aussi corrigée).
    Citation Envoyé par CinéPhil
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT c1.numcmi AS antecedent,
    	c1.datecmi AS date_antecedent,
    	c2.numcmi AS avis,
    	c2.datecmi AS date_avis
    FROM 
    (
    	SELECT numcmi, datecmi, numcmiref
    	FROM cmi_cmi
    	WHERE datecmi BETWEEN '".$dateA."' AND '".$dateB."'
    ) tmp
    INNER JOIN cmi_cmi c1 ON tmp.numcmiref = c1.numcmi
    	INNER JOIN cmi_cmi c2 ON c1.numcmi = c2.numcmiref
    ORDER BY c1.datecmi, c2.datecmi
    Tu as répondu ceci au message #7 :
    Citation Envoyé par BMATH
    Bon, malheureusement, ta requête ne passe pas du tout : page vide, comme quand on fait une faute de syntaxe.
    Tu l'as essayée où ? Dans ton application ou dans le SGBD ?

    Je viens de tester avec les données que tu as fournies dans ton message #4 et ça semble fonctionner.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

Discussions similaires

  1. Classement alphanumérique avec ORDER BY
    Par bart64 dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 07/10/2007, 21h19
  2. Réponses: 1
    Dernier message: 17/08/2006, 20h27
  3. Obtenir numéro d'un classement avec ORDER BY
    Par jersey_girl dans le forum Requêtes
    Réponses: 3
    Dernier message: 08/08/2006, 23h49
  4. [Oracle 10] Bizzareté requête avec order by ??
    Par Eric.H dans le forum Oracle
    Réponses: 12
    Dernier message: 22/06/2005, 12h36
  5. PB avec Order By
    Par Desraux dans le forum SQL
    Réponses: 2
    Dernier message: 15/09/2004, 16h16

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