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

Langage SQL Discussion :

Comment avoir la liste des patients absents à leurs 3 derniers Rdv


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2002
    Messages : 264
    Par défaut Comment avoir la liste des patients absents à leurs 3 derniers Rdv
    Bonjour,
    J'ai 1 table Patient (Id, Nom...) et 1 Table RdvPatient (IdPatient, Date, IsAbsent...).
    Comment demander la liste des patient absents à leurs X derniers Rdv (par date), X devant être 1 paramètre passé.
    Merci pour votre aide
    PS : Sql Server 2014

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 999
    Billets dans le blog
    6
    Par défaut
    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
    WITH 
    T0 AS
    -- recherche des trois derniers RV du patient
    (SELECT PRV_ID, PAT_ID,  
            ROW_NUMBER() OVER(PARTITION BY PAT_ID ORDER BY RDV_DATE_HEURE DESC) AS N
     FROM   T_PATIENT_RENDEZVOUS_PRV),
    T1 AS
    -- y a t-il un des 3 derniers RV qui a été honoré ?
    (SELECT PAT_ID
     FROM   T_PATIENT_RENDEZVOUS_PRV AS PRV
            JOIN T0 ON PRV.PRV_ID = T0.PRV
     WHERE  PRV_PRESENT = 10)
    -- résultat final
    SELECT *
    FROM   T_PATIENT_PAT AS PAT
    WHERE  PAT_ID IN (SELECT PAT_ID
                      FROM   T0
                      EXCEPT
                      SELECT PAT_ID
                      FROM   T1);
    Pour vous former, mon livre sur SQL :
    Nom : SQL.jpg
Affichages : 313
Taille : 47,4 Ko

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2002
    Messages : 264
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    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
    WITH 
    T0 AS
    -- recherche des trois derniers RV du patient
    (SELECT PRV_ID, PAT_ID,  
            ROW_NUMBER() OVER(PARTITION BY PAT_ID ORDER BY RDV_DATE_HEURE DESC) AS N
     FROM   T_PATIENT_RENDEZVOUS_PRV),
    T1 AS
    -- y a t-il un des 3 derniers RV qui a été honoré ?
    (SELECT PAT_ID
     FROM   T_PATIENT_RENDEZVOUS_PRV AS PRV
            JOIN T0 ON PRV.PRV_ID = T0.PRV
     WHERE  PRV_PRESENT = 10)
    -- résultat final
    SELECT *
    FROM   T_PATIENT_PAT AS PAT
    WHERE  PAT_ID IN (SELECT PAT_ID
                      FROM   T0
                      EXCEPT
                      SELECT PAT_ID
                      FROM   T1);
    Merci, ça a l'air de faire pas mal mais je ne comprends pas ou je peux donner le nombre d'absences souhaitées...

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    Bonjour,

    Voici une solution utilisant des fonctions analytiques. J'ai supposé que IsAbsent = 1 pour signaler une absence. La requête ne montre que les patients ayant manqué leurs X derniers rdv, avec les dates correspondantes:

    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
    with rdv as (select p.id,
                        p.nom, 
                        r.date_rdv,
                        row_number() over (partition by p.id order by r.date_rdv desc) rn,
                        sum(case when r.isabsent = 1 then 1 else 0 end) over (partition by p.id order by r.date_rdv desc) somme_rdv_absent
                 from patient p
                 join RdvPatient r on r.idpatient = p.id
                ),
         X_derniers_rdv as (select id, 
                                   nom,
                                   date_rdv,
                                   max(somme_rdv_absent) over (partition by id) nb_rdv_manques
                            from rdv
                            where rn <= :X
                           )
    select id, 
           nom,
           date_rdv
    from X_derniers_rdv
    where nb_rdv_manques = :X;

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    Si tu es en Oracle 12c, c'est encore plus simple avec une requête match_recognize:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select id, nom, date_rdv 
    patient p
    join RdvPatient r on r.idpatient = p.id
    match_recognize
     (partition by id
      order by date_rdv desc
      all rows per match
      pattern(^rdv_manque{:X})
      define rdv_manque as rdv_manque.isabsent=1
     );

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    bonjour,

    Ou bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    WITH RangRDV AS (
    		SELECT *, ROW_NUMBER() OVER(PARTITION BY idpatient ORDER BY dte DESC) AS RN
    		FROM RdvPatient
    	)
    SELECT p.Nom
    FROM Patient AS P
    INNER JOIN RangRDV AS R
    	ON	R.idpatient = P.id
    WHERE RN <= @x
    GROUP BY p.Nom
    HAVING SUM(IsAbsent)  = 3

  7. #7
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2002
    Messages : 264
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    bonjour,

    Ou bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    WITH RangRDV AS (
    		SELECT *, ROW_NUMBER() OVER(PARTITION BY idpatient ORDER BY dte DESC) AS RN
    		FROM RdvPatient
    	)
    SELECT p.Nom
    FROM Patient AS P
    INNER JOIN RangRDV AS R
    	ON	R.idpatient = P.id
    WHERE RN <= @x
    GROUP BY p.Nom
    HAVING SUM(IsAbsent)  = 3
    Merci, ça me plait bien comme technique mais j'avais simplifié en pensant que je pourrais adapter... et je n'y arrive pas.
    En fait je n'ai pas IsAbs = 1 mais AbsID qui vaut 1 à 49 qd c'est 1 absence...
    Si tu pouvais me proposer ta solution en adaptant cette variante ce serait parfait.

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    et quand ce n'est pas une absence ?

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Sur SQL-Server vous pouvez faire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    declare @N int;
    set @N=3;
     
         select P.Id, P.Nom
           from Patient as P
    cross apply (  select top (@N)
                           case when R.AbsID between 1 and 49 then 1 else 0 end
                     from RdvPatient as R
                    where R.IdPatient = P.Id
                 order by R.[Date] desc
                ) as A (IsAbsent)
       group by P.Id, P.Nom
         having sum(A.IsAbsent) = @N;
    Le 3 étant dans le top du cross apply et dans le having final.

    Edit: prise en compte de l'AbsID et paramétrisation du nombre d'absences.

  10. #10
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2002
    Messages : 264
    Par défaut
    Citation Envoyé par vanagreg Voir le message
    Si tu es en Oracle 12c, c'est encore plus simple avec une requête match_recognize:
    ...hélas non, j'avais oublié de préciser : Sql Server 2014

  11. #11
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2002
    Messages : 264
    Par défaut
    Citation Envoyé par vanagreg Voir le message
    Bonjour,

    Voici une solution utilisant des fonctions analytiques. J'ai supposé que IsAbsent = 1 pour signaler une absence. La requête ne montre que les patients ayant manqué leurs X derniers rdv, avec les dates correspondantes:

    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
    with rdv as (select p.id,
                        p.nom, 
                        r.date_rdv,
                        row_number() over (partition by p.id order by r.date_rdv desc) rn,
                        sum(case when r.isabsent = 1 then 1 else 0 end) over (partition by p.id order by r.date_rdv desc) somme_rdv_absent
                 from patient p
                 join RdvPatient r on r.idpatient = p.id
                ),
         X_derniers_rdv as (select id, 
                                   nom,
                                   date_rdv,
                                   max(somme_rdv_absent) over (partition by id) nb_rdv_manques
                            from rdv
                            where rn <= :X
                           )
    select id, 
           nom,
           date_rdv
    from X_derniers_rdv
    where nb_rdv_manques = :X;
    Merci pour ton aide.
    Le résultat n'est pas tout à fait celui attendu : si je demande la liste des ceux absents aux 3 derniers Rdv, le patient sort 3 fois avec chaque fois la date du Rdv.
    ...je voulais 1 liste de patients (chacun 1 seule fois), pas 1 liste de Rdv manqués.
    Je pense qu'on doit pouvoir la modifier pour cela mais c'est trop complexe pour mon petit niveau...

  12. #12
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    Citation Envoyé par bib34690 Voir le message
    Merci pour ton aide.
    Le résultat n'est pas tout à fait celui attendu : si je demande la liste des ceux absents aux 3 derniers Rdv, le patient sort 3 fois avec chaque fois la date du Rdv.
    ...je voulais 1 liste de patients (chacun 1 seule fois), pas 1 liste de Rdv manqués
    Oui c'était pour avoir les dates de rdv manqués. Si tu n'en as pas besoin alors utilises la version de aieeeuuuuu.

  13. #13
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    tu peux modifier la clause having:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HAVING SUM(case when IsAbsent between 1 and 49 then 1 else 0 end)  = 3

  14. #14
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2002
    Messages : 264
    Par défaut
    Citation Envoyé par vanagreg Voir le message
    tu peux modifier la clause having:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HAVING SUM(case when IsAbsent between 1 and 49 then 1 else 0 end)  = 3
    PARFAIT : fait le job, simple à comprendre, rapide.
    Merci

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

Discussions similaires

  1. [Python 2.X] comment avoir la list des EVT_ et leur actions ?
    Par tsumey dans le forum wxPython
    Réponses: 5
    Dernier message: 28/03/2016, 08h42
  2. Réponses: 1
    Dernier message: 04/04/2013, 00h26
  3. Réponses: 4
    Dernier message: 26/03/2009, 14h58
  4. comment avoir la liste des programmes dans le systray ? Merci
    Par eric_xrx dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 25/01/2009, 20h00
  5. Réponses: 3
    Dernier message: 17/08/2007, 16h17

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