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

  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
    Normalement, ma sous-requête donne les numcmi compris entre deux dates.
    La jointure de cette sous requête avec la table donne les antécédents des ces numcmi.

    Maintenant si tu veux tous les décendants des antécédents, il faut une autre jointure :
    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
    	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
    Par contre avec cette requête, le numcmi d'origine, celui compris entre deux dates, est noyé quelque part dans son groupe.
    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 !

  8. #8
    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 patience et ton investissement sur mon problème, c'est sympa !

    J'ignorais qu'on pouvait faire plusieurs jointures sur la même table

    Bon, malheureusement, ta requête ne passe pas du tout : page vide, comme quand on fait une faute de syntaxe. Pourtant, j'ai relu une dizaine de fois, il ne manque rien, et quand je remplace ta requête par une requête simple, pas de souci d'affichage.

    Il se fait tard, je n'y vois plus bien clair, je me repenche dessus dès que j'ai un moment

  9. #9
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    je voudrais afficher entre une date A et une date B tous les avis formulés,
    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.
    Déjà si vous me permettez, avant de vous proposer une solution de requête, il me semble qu'il y a une petite incompatibilité entre ces deux assertions. Car si la première citation fait partie intégrante du cahier des charges de votre requête, vous obtiendez forcément un pack de numcmiref en N exemplaires et non un seul si N avis sont donnés dans la période, et ceci est incontournable, sauf à faire une aggrégation sur les numcmi pour chaque mumcmiref.

    Ceci étant dit, reste à régler une chose :
    ...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
    Cela ne pose pas de problème en soit de sortir l'information, mais de façon à optimiser l'écriture de la requête, il est important de connaître préalablement la signature de la requête que vous avez besoin d'obtenir au niveau de la vue de votre IHM.

    A mon sens cependant, pour que le résultat d'une telle requête reste lisible et puisse être facilement traitée au niveau applicatif, une solution serait d'aggréger pour chaque numcmi sont historique antérieur à A lorsqu'il existe, et en cas d'absence le déterminer à NULL par effet de jointure.
    Si l'avantage d'une telle solution est d'avoir un résultat relativement facile à lire, il a un inconvénient :
    Dans le cas de figure où un numcmi possède à la fois un historique sur l'intervalle [A-B] et un historique antérieur à A, dans un contexte où l'historique doit être "prioritairement facilement extrait" de la requête pour des besoins de limitation de traitement applicatif pour l'affichage, la reconstitution de l'historique obligerait à retraiter les resultats de la requête par aggrégation des résultats sur l'intervalle et hors de l'intervalle.
    La solution serait par exemple d'aggréger l'historique complet relatif à chaque numcmi sur une colonne.
    Ainsi vous auriez l'historique sur [A-B] à travers la liste ordonnée des numcmi via les lignes de la requête, et l'historique complet par aggregation.
    Cela génère une redondance et peut être gourmand en ressources selon la volumétrie de la base, la largeur de l'intervalle, et la qualité de votre normalisation et de vos indexs mais merci de me faire un retour sur comment vous voyez les choses à ce niveau.

    ++

    EDIT: Dans ma vision de votre problème, la gestion sur l'intervalle se ferait ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT  numcmi, numcmiref FROM cmi_cmi WHERE datecmi BETWEEN '$dateA' AND '$dateB' GROUP BY numcmiref ORDER BY datecmi DESC
    Reste à y rajouter l'historique hors intervalle par dérivation et à l'adapter selon votre choix d'aggrégation / ou votre besoin au niveau de la signature.

  10. #10
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    La nuit portant conseil, une autre possibilité serait de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT  numcmi, numcmiref, datecmi 
    FROM cmc_cmi 
    WHERE numcmiref IN 
         (SELECT numcmiref 
          FROM cmi_cmi 
          WHERE datecmi BETWEEN '$dateA' AND '$dateB' 
          GROUP BY numcmiref 
          ORDER BY datecmi DESC)
    AND datecmi <= '$dateB'  
    GROUP BY numcmiref 
    ORDER BY datecmi DESC
    Qui normalement doit vous sortir l'historique classé des avis du plus récent au plus ancien regroupé par dossier client des dossiers concernés par les avis émis sur la période [A-B].

    C'est en fait la solution la plus simple si vous n'avez pas besoin d'un indicateur supplémentaire pour identifier les avis de l'intervalle.

    En espérant vous avoir aidé.

    Jc

  11. #11
    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 beaucoup pour ces explications et propositions.

    Je regarde ça en détail dès que j'ai un moment.

  12. #12
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Puisque l'on y est, si vous voulez obtenir un indicateur d'appartenance à l'intervalle [A-B] de vos avis au niveau des résultats de votre requête pour éviter de le faire au niveau applicatif, ce qui est légitime, car cela obligerait à faire une itération de contrôle complètement contre-productive et contre-performante, il suffit de modifier la requête proposée 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 numcmi, numcmiref, datecmi, (CASE WHEN datecmi < '$dateA' THEN 'OUT' ELSE 'IN' END) AS interval 
    FROM cmc_cmi 
    WHERE numcmiref IN 
          (SELECT numcmiref 
        FROM cmi_cmi  
        WHERE datecmi BETWEEN '$dateA' AND '$dateB' 
        GROUP BY numcmiref 
        ORDER BY datecmi DESC)
          AND datecmi <= '$dateB' 
    GROUP BY numcmiref 
    ORDER BY datecmi DESC
    ++

  13. #13
    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 beaucoup pour ces explications et propositions.

    Je regarde ça en détail dès que j'ai un moment.
    3 mois plus tard, je trouve enfin un moment pour me pencher dessus !


    Tse, je dois avouer que j'ai complètement perdu pied en lisant ton premier message : je comprends aisément que se poser les bonnes questions avant de bâtir est un préalable indispensable pour faire les choses bien.
    Mais en tant que newbie et programmateur du dimanche, je me heurte à des concepts que je ne maitrise absolument pas (signature de requête, IHM, niveau applicatif,...), ou d'autres que "j'intuite" tout juste. Autant dire que je suis incapable de répondre à tes questions.


    Bon, je comprends plus aisément la philosophie de ta proposition dans ton 2e message (en remplaçant le cmc_cmi par cmi_cmi). Si je comprends bien la structure, le "ORDER BY" de la sous-requête n'apporte d'ailleurs rien de plus. Si le résultat a le mérite de ne présenter qu'une seule fois chaque patient, et de présenter tous les avis (d'avant et de pendant l'intervalle) dans l'ordre chronologique pour chaque patient, 2 soucis :
    1. la requête semble gourmande en ressources ? (plusieurs secondes pour une cinquantaine de résultats, là où d'autres requêtes (les fameuses qui m'affichent les blocs en N exemplaires) sont instantanées)
    2. les "blocs" par patient sont classés par ordre chronologique DESC sur la base du 1er avis donné pour chaque patient, et non du dernier avis. J'aimerais que ce soit sur la base du dernier avis.


    Ta dernière proposition génère une erreur de syntaxe (même en remplaçant le cmc_cmi par cmi_cmi) :
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval FROM cmi_cmi WHERE numcmiref IN (SELECT numcmiref FROM cmi_cmi WHERE da' at line 1

    Je cherche de mon côté également, en bidouillant à partir des propositions que vous m'avez faites...

  14. #14
    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
    et finalement, si je faisais une sous-requête type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT numcmiref, 
    MAX(datecmi) as MaxDateCmi
    FROM cmi_cmi 
    WHERE datecmi BETWEEN '$dateA' AND '$dateB' 
    GROUP BY numcmiref
    ORDER BY MaxDateCmi
    Est-ce que ça ne permettrait pas de récupérer ensuite (une seule fois) tous les numcmiref de la période, classés par ordre de dernier avis MaxDateCmi ? (bon, je n'en suis pas encore à écrire la requête imbriquée [requête - sous-requête] : je ne suis pas super à l'aise pour la syntaxe...)

  15. #15
    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
    INTERVAL est un mot réservé du langage SQL. C'est probablement la cause de l'erreur de syntaxe. Remplace l'alias par un autre mot ou entoure le d'apostrophes ou de guillemets.
    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 !

  16. #16
    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 EUREKA !
    Merci CinePhil. Avec "Intervalle" au lieu de "Interval", je n'ai effectivement plus de problème de syntaxe. Mais requête longue ++, comme la 2e de Tse.


    Par contre, la requête que je viens de vous présenter me permet (sans l'utiliser en sous-requête, mais telle quelle) effectivement de récupérer tous mes numcmiref dans l'ordre voulu, en un seul exemplaire chacun :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT numcmiref, 
    MAX(datecmi) AS MaxDateCmi
    FROM cmi_cmi 
    WHERE datecmi BETWEEN '$dateA' AND '$dateB' 
    GROUP BY numcmiref
    ORDER BY MaxDateCmi
    Après, je passe en revue chaque numcmiref, et pour chacun, je fais une seconde requête pour récupérer tout l'historique jusqu'à dateB, pour afficher le "bloc" du patient concerné.

    C'est tellement bête que j'en suis presque navré de vous avoir embarqués à chercher des trucs compliqués !

    Ce problème est donc a priori résolu en ce qui me concerne, puisque j'ai le résultat voulu. Merci à tous ceux qui ont pris le temps de faire chauffer quelques neurones pour m'aider !

  17. #17
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    D'abord veuillez m'excuser de n'avoir pu répondre plus tôt, travail oblige.

    Pour votre réponse,

    1) Désolé pour le mot clé interval, un petit moment d'égarement de ma part
    2) Concernant la longueur d'exécution de la requête, il est clair que l'instruction case ralonge le temps d'exécution du plan de requête par rapport à un contexte où il n'y serait pas, mais je pense que votre plan de requête actuel doit faire des fulls scan sur votre table, ce qui me laisse à penser à une absence d'indexs ou d'indexs non pertinents sur votre table. Je vous rappele cependant que cette solution avec le renseignement des avis sur l'intervalle reste optionnel, selon vos besoins, et que la requête initiale fait le même travail.
    3)
    Après, je passe en revue chaque numcmiref, et pour chacun, je fais une seconde requête pour récupérer tout l'historique jusqu'à dateB, pour afficher le "bloc" du patient concerné.
    Donc si vous avez disons 200 numcmiref, vous faites une itération en PHP (passable) dessus et vous soumettez 200 nouvelles requêtes au SGBDR? Vous devriez reconsidérer votre point de vue sur la question des performances de votre solution par rapport à la mienne / ou tout autre solution 100% SGBDR.

    Cordialement,

    tse_jc

  18. #18
    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 !

  19. #19
    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
    Citation Envoyé par tse_jc Voir le message
    Donc si vous avez disons 200 numcmiref, vous faites une itération en PHP (passable) dessus et vous soumettez 200 nouvelles requêtes au SGBDR?
    C'est bien ça... Surement pas propre, mais j'ai mon résultat à la clé, alors ça m'allait bien...
    Je n'avais pas du tout conscience du caractère aberrant d'envoyer 50, 100 voire effectivement 200 requêtes successives : n'ayant aucune base théorique en programmation, c'est vrai que je n'ai aucune notion de ressource ou de surcharge...

    Bon, je comprends que je "peux mieux faire", et même que je dois mieux faire, surtout quand je vois l'énergie que vous y mettez.
    Je n'ai pas bien le temps de m'y recoller tout de suite, mais je vous promets de ne pas en rester là et d'y revenir dès que j'ai un moment.

    Cinephil, ta nouvelle requête passe bien et renvoie bien des résultats, mais il y a plein de doublons : Voici un copier-coller de quelques lignes de résultats pour les champs antecedent - date_antecedent - avis - date_avis
    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
    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
    1764 - 2012-09-11 - 1764 - 2012-09-11
    1764 - 2012-09-11 - 1764 - 2012-09-11
    1764 - 2012-09-11 - 1764 - 2012-09-11
    1764 - 2012-09-11 - 1769 - 2012-09-12
    1764 - 2012-09-11 - 1769 - 2012-09-12
    1764 - 2012-09-11 - 1769 - 2012-09-12
    1764 - 2012-09-11 - 1769 - 2012-09-12
    1764 - 2012-09-11 - 1795 - 2012-09-19
    1764 - 2012-09-11 - 1795 - 2012-09-19
    1764 - 2012-09-11 - 1795 - 2012-09-19
    1764 - 2012-09-11 - 1795 - 2012-09-19
    1764 - 2012-09-11 - 1802 - 2012-09-21
    1764 - 2012-09-11 - 1802 - 2012-09-21
    1764 - 2012-09-11 - 1802 - 2012-09-21
    1764 - 2012-09-11 - 1802 - 2012-09-21
    1764 - 2012-09-11 - 1824 - 2012-09-23
    1764 - 2012-09-11 - 1824 - 2012-09-23
    1764 - 2012-09-11 - 1824 - 2012-09-23
    1764 - 2012-09-11 - 1824 - 2012-09-23
    1764 - 2012-09-11 - 1867 - 2012-10-10
    1764 - 2012-09-11 - 1867 - 2012-10-10
    1764 - 2012-09-11 - 1867 - 2012-10-10
    1764 - 2012-09-11 - 1867 - 2012-10-10
    1764 - 2012-09-11 - 1882 - 2012-10-15
    1764 - 2012-09-11 - 1881 - 2012-10-15
    1764 - 2012-09-11 - 1881 - 2012-10-15
    1764 - 2012-09-11 - 1881 - 2012-10-15
    1764 - 2012-09-11 - 1881 - 2012-10-15
    1764 - 2012-09-11 - 1882 - 2012-10-15
    1764 - 2012-09-11 - 1882 - 2012-10-15
    1764 - 2012-09-11 - 1882 - 2012-10-15
    1764 - 2012-09-11 - 1906 - 2012-10-23
    1764 - 2012-09-11 - 1906 - 2012-10-23
    1764 - 2012-09-11 - 1906 - 2012-10-23
    1764 - 2012-09-11 - 1906 - 2012-10-23
    1770 - 2012-09-12 - 1770 - 2012-09-12
    1770 - 2012-09-12 - 1770 - 2012-09-12
    1770 - 2012-09-12 - 1770 - 2012-09-12
    1770 - 2012-09-12 - 1770 - 2012-09-12
    1770 - 2012-09-12 - 1770 - 2012-09-12
    1770 - 2012-09-12 - 1786 - 2012-09-18
    1770 - 2012-09-12 - 1786 - 2012-09-18
    1770 - 2012-09-12 - 1786 - 2012-09-18
    1770 - 2012-09-12 - 1786 - 2012-09-18
    1770 - 2012-09-12 - 1786 - 2012-09-18
    1770 - 2012-09-12 - 1804 - 2012-09-22
    1770 - 2012-09-12 - 1804 - 2012-09-22
    1770 - 2012-09-12 - 1804 - 2012-09-22
    Pareil : je la décortique en détails dès que possible.

    Merci, en tout cas !

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