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 :

Simplifier requête SQL


Sujet :

Langage SQL

  1. #21
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    je met quoi dans le GROUP BY ? J'ai tester avec : GROUP BY pat.nip.


    Sinon voici les résultats obtenu :

    - Requête originale :


    - Requête simplifier :


  2. #22
    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
    Le principe général est que le GROUP BY doit contenir toutes les colonnes du SELECT qui n'ont pas d'opérations de regroupement (SUM, MAX, MIN, AVG, COUNT).

    En reprenant la proposition de tbc92, ça donnerait ceci, si Oracle veut bien grouper par les alias des colonnes du SELECT :
    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
    SELECT
        pat.nom NOM,
        pat.sexe SEXE,
        pat.nip ipp,
        SUBSTR(datenais, 1, 4) ANNEE_NAISSANCE,
        SUBSTR(datenais, 5, 2) MOIS_NAISSANCE,
        SUBSTR(datenais, 7, 2) JOUR_NAISSANCE,
        DECODE(pat.PATRONYME, null, pat.NOM, '', pat.NOM, pat.PATRONYME) NOM_NAISSANCE,
        pat.prenom PRENOM,
        infpat.NUMSECU NSS,
        DECODE(infpat.NUMSECU, null, '', '', '', substr(infpat.NUMSECU, 6, 2)) DEP_NAISSANCE,
        DECODE(infpat.NUMSECU, null, '', '', '', substr(infpat.NUMSECU, 8, 3)) VILLE_NAISSANCE,
        DECODE(srv.nietablis, 1, 'MZ', 3, 'MZ', 4, 'MZ', 5, 'MZ', 8, 'MZ', 9, 'MZ', 10, 'TH', 11, 'TH', 12, 'TH', 13, 'TH', 14, 'TH', 15, 'TH', 16, 'TH', 17, 'TH', 18, 'TH', 19, 'TH', 20, 'MZ', 21, 'TH', 22, 'MZ', 23, 'TH', 25, 'TH', 24, 'MZ', 'Autre') etb,
    	MIN ( CASE
    		WHEN q.NIQ = 4993 THEN bmr.code
    	END )  AS PatientNiveauEtudes049,
    	MIN ( CASE
    		WHEN q.NIQ = 5023 THEN bmr_code
    	END ) AS PAtientEnvoyePar051
    	-- etc. sur le même principe
    FROM bm_th_s th 
    INNER JOIN patient pat ON pat.nipatient = th.nipatient 
    	LEFT OUTER JOIN infopat infpat ON pat.nipatient = infpat.nipatient
    INNER JOIN ej_srv srv ON th.niservice = srv.niservice
    -- Jointures pour les sous-requêtes corrélées
    INNER JOIN BM_TH_S bmt ON bmt.nith = th.nith
    	INNER JOIN BM_LIB_S bml ON bml.NITH = bmt.NITH
    		INNER JOIN BM_REP_S bmr ON bmr.NILIB = bml.NILIB
    			INNER JOIN C_QUESTION q ON bml.NIQ = q.NIQ
    WHERE th.niquest = '194'
    	AND th.retrait = 'F'
    	AND SUBSTR(dates, 0, 8) = TO_CHAR(SYSDATE, 'yyyymmdd')
    	AND srv.retrait = 'F'
    GROUP BY NOM, SEXE, ipp, ANNEE_NAISSANCE, MOIS_NAISSANCE, JOUR_NAISSANCE, NOM_NAISSANCE, PRENOM, NSS, DEP_NAISSANCE, VILLE_NAISSANCE, etb
    Le test à faire avec ce début de requête, c'est de voir si les deux colonnes calculées (les MIN(CASE...) sont bien renseignées.
    Ensuite il suffit d'appliquer le même principe sur le reste de la requête.
    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. #23
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    les alias ne fonctionnent pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-00904: "ETB" : identificateur non valide

  4. #24
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    Bon, déjà ça :

    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
    SELECT
        -- 1ere Partie
        pat.nom    NOM,
        pat.prenom PRENOM,
        pat.sexe   SEXE,
        pat.nip    IPP,
        -- 2eme Partie*/
        MIN(CASE WHEN q.NIQ = 4993 THEN bmr.CODE END) AS PatientNiveauEtudes049
     
    FROM
        BM_TH_S th
        INNER JOIN      PATIENT pat    ON pat.nipatient = th.nipatient
        LEFT OUTER JOIN INFOPAT infpat ON pat.nipatient = infpat.nipatient
        INNER JOIN      EJ_SRV  srv    ON th.niservice  = srv.niservice
        -- Jointures pour les sous-requêtes corrélées
        INNER JOIN BM_TH_S      bmt    ON bmt.nith      = th.nith
        INNER JOIN BM_LIB_S     bml    ON bmt.NITH      = bml.NITH
        INNER JOIN BM_REP_S     bmr    ON bml.NILIB     = bmr.NILIB
        INNER JOIN C_QUESTION   q      ON bml.NIQ       = q.NIQ
     
    WHERE
        th.niquest  = '194' AND                                  -- Identifiant du Questionnaire de référence
        th.retrait  = 'F'   AND                                  -- Etat de la supression logique du document
        srv.retrait = 'F'   AND                                  -- Drapeau de supression de l'enregistrement
        substr(th.dates, 0, 8) = to_char(sysdate-1, 'yyyymmdd')  -- Date du jour 
     
    GROUP BY pat.nom, pat.prenom, pat.sexe, pat.nip;
    à l'air de fonctionner.

  5. #25
    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
    les alias ne fonctionnent pas
    ORA-00904: "ETB" : identificateur non valide
    C'est bizarre qu'il ne commence à tiquer qu'au dernier alias ! Tu es sûr que tu as bien repris identiquement l'alias de la colonne du SELECT dans le GROUP BY ?

    Si oui, alors essaie avec les numéros de colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT
        pat.nom NOM,
        pat.sexe SEXE,
        pat.nip ipp,
        SUBSTR(datenais, 1, 4) ANNEE_NAISSANCE,
        SUBSTR(datenais, 5, 2) MOIS_NAISSANCE,
        SUBSTR(datenais, 7, 2) JOUR_NAISSANCE,
        DECODE(pat.PATRONYME, null, pat.NOM, '', pat.NOM, pat.PATRONYME) NOM_NAISSANCE,
        pat.prenom PRENOM,
        infpat.NUMSECU NSS,
        DECODE(infpat.NUMSECU, null, '', '', '', substr(infpat.NUMSECU, 6, 2)) DEP_NAISSANCE,
        DECODE(infpat.NUMSECU, null, '', '', '', substr(infpat.NUMSECU, 8, 3)) VILLE_NAISSANCE,
        DECODE(srv.nietablis, 1, 'MZ', 3, 'MZ', 4, 'MZ', 5, 'MZ', 8, 'MZ', 9, 'MZ', 10, 'TH', 11, 'TH', 12, 'TH', 13, 'TH', 14, 'TH', 15, 'TH', 16, 'TH', 17, 'TH', 18, 'TH', 19, 'TH', 20, 'MZ', 21, 'TH', 22, 'MZ', 23, 'TH', 25, 'TH', 24, 'MZ', 'Autre') etb,
    12 colonnes avant le premier MIN donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
    Si ça ne fonctionne pas alors il faut reprendre le détail du SELECT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GROUP BY pat.nom, pat.sexe, pat.nip, SUBSTR(datenais, 1, 4), SUBSTR(datenais, 5, 2) -- etc. Je sais, c'est chiant !
    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 !

  6. #26
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    Merci, finalement ça à l'air de fonctionner avec ceci :

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    SELECT
        /* -------------------------------------- 1ere Partie -------------------------------------- */
        pat.NOM                                    AS NOM,
        pat.PRENOM                                 AS PRENOM,
        pat.SEXE                                   AS SEXE,
        pat.NIP                                    AS IPP,
        substr(pat.DATENAIS, 1, 4)                 AS ANNEE_NAISSANCE,
        substr(pat.DATENAIS, 5, 2)                 AS MOIS_NAISSANCE,
        substr(pat.DATENAIS, 7, 2)                 AS JOUR_NAISSANCE,
        decode(pat.PATRONYME, 
                   null, pat.NOM, 
                     '', pat.NOM, 
                     pat.PATRONYME)                AS NOM_NAISSANCE,
        infpat.NUMSECU                             AS NSS,
        decode(infpat.NUMSECU, 
                   null, '', 
                     '', '', 
                     substr(infpat.NUMSECU, 6, 2)) AS DEP_NAISSANCE,
        decode(infpat.NUMSECU, 
                   null, '', 
                     '', '', 
                     substr(infpat.NUMSECU, 8, 3)) AS VILLE_NAISSANCE,
        decode(srv.NIETABLIS, 
                    1, 'MZ',  3, 'MZ',  4, 'MZ',  
                    5, 'MZ',  8, 'MZ',  9, 'MZ', 
                   24, 'MZ', 10, 'TH', 11, 'TH', 
                   12, 'TH', 13, 'TH', 14, 'TH', 
                   15, 'TH', 16, 'TH', 17, 'TH', 
                   18, 'TH', 19, 'TH', 20, 'MZ', 
                   21, 'TH', 22, 'MZ', 23, 'TH', 
                   25, 'TH', 'Autre')              AS etb,
        /* -------------------------------------- 2eme Partie -------------------------------------- */
        MIN(CASE WHEN q.NIQ = 4993 THEN bmr.CODE END) AS PatientNiveauEtudes049,
        MIN(CASE WHEN q.NIQ = 5023 THEN bmr.CODE END) AS PatientSituationGeo050,
        MIN(CASE WHEN q.NIQ = 4988 THEN bmr.CODE END) AS PAtientEnvoyePar051,
        MIN(CASE WHEN q.NIQ = 6025 THEN bmr.CODE END) AS DclEtatDemence052,
        MIN(CASE WHEN q.NIQ = 6035 THEN bmr.CODE END) AS DclDiagnostic054,
        MIN(CASE WHEN q.NIQ = 6026 THEN bmr.CODE END) AS DclTypeActe055,
        MIN(CASE WHEN q.NIQ = 4992 THEN bmr.CODE END) AS DclModeDeVie060,
        MIN(CASE WHEN q.NIQ = 6033 THEN bmr.CODE END) AS DclFinSuivi064,
        MIN(CASE WHEN q.NIQ = 6029 THEN bmr.CODE END) AS PatientProfession112, 
        MIN(CASE WHEN q.NIQ = 6030 THEN bmr.CODE END) AS PatientAccompagnant113,
        /* -------------------------------------- 3eme Partie -------------------------------------- */
        MIN(CASE WHEN q.NIQ = 6031 THEN bmr.REPONSE END) AS DclAnneePremierDiag053,
        MIN(CASE WHEN q.NIQ = 5015 THEN bmr.REPONSE END) AS DcllADLDetection058,
        MIN(CASE WHEN q.NIQ = 5014 THEN bmr.REPONSE END) AS DcllADLConsequence059,
        /* -------------------------------------- 4eme Partie -------------------------------------- */
        MIN(CASE WHEN q.NIQ = 4967 THEN decode(bmr.REPONSE, 'Non', 'N', 'Oui', 'O','SR') END) AS DclEffetIndesirable078,
        MIN(CASE WHEN q.NIQ = 4967 THEN decode(bmr.REPONSE, 'Oui', 'O', 'Non', 'N'     ) END) AS DclPR097,
        /* -------------------------------------- 5eme Partie -------------------------------------- */
        MIN(CASE WHEN q.NIQ = 4964 THEN substr(bmr.REPONSE, 0, 2)||substr(bmr.REPONSE, 4, 2)||substr(bmr.REPONSE, 7, 4) END) AS DclDateActe056,
        MIN(CASE WHEN q.NIQ = 6034 THEN substr(bmr.REPONSE, 0, 2)||substr(bmr.REPONSE, 4, 2)||substr(bmr.REPONSE, 7, 4) END) AS DclDateFinSuivi065,
        /* -------------------------------------- 6eme Partie -------------------------------------- */
          decode((MIN(CASE WHEN q.NIQ = 4956 THEN bmr.CODE END)), '', 'SI', MIN((CASE WHEN q.NIQ = 4956 THEN bmr.CODE END))) DclAPA061,
        decode(MIN((CASE WHEN q.NIQ = 4955 THEN bmr.CODE END)), '', 'SI', MIN((CASE WHEN q.NIQ = 4955 THEN bmr.CODE END))) DclALD062,
        /* -------------------------------------- 7eme Partie -------------------------------------- */
        decode((MIN(CASE WHEN q.NIQ = 6567 THEN bmr.REPONSE END)), null, '', MIN((CASE WHEN q.NIQ = 6567 THEN bmr.REPONSE END))) DclMMSE057,
        /* -------------------------------------- 8eme Partie -------------------------------------- */
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Sans aucun traitement pharmaceutique'           THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPAucun068, 
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Inhibiteurs de l''acétylcholiestérase'          THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPInhibAcetyl069,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Antagonistes des récepteurs NMDA'               THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPAntagonisteNMDA070,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Antidépresseurs'                                THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPAntidepresseurs071,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Neuroleptiques'                                 THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPNeuroleptiques072,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Anxiolitiques'                                  THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPAnxiolitiques073,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Hypnotiques'                                    THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPHypnotiques074,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Nootropes'                                      THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPNootropes075,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Autres traitements pharmacologiques chroniques' THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPAutres076,
        decode((MIN(CASE WHEN q.NIQ = 5035 AND bmr.reponse = 'Patient traité par aucun des traitements listés'THEN bmr.REPONSE END)), NULL, 'N', 'O') DclTPAucunDansListe077,
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Aucune prise en charge'                         THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRAucun079,
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par un orthophoniste'                           THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSROrthophoniste080, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par un psychologue'                             THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRPsychologue081,
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par un kinésithérapeute'                        THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRKinesitherapeute082, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par un ergothérapeute'                          THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRErgotherapeute083, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par un groupe d''intervenants'                  THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRGroupe084, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par un accueil de jour'                         THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRAccueilJour085, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par MAIA'                                       THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRMaia086, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par CLIC'                                       THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRClic087, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par une plateforme de répits'                   THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRRepits088, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Par SSIAD'                                      THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRSiad089, 
        decode((MIN(CASE WHEN q.NIQ = 4997 AND bmr.reponse = 'Autre type de prise en charge'                  THEN bmr.REPONSE END)), NULL, 'N', 'O') DclIPSRAutre090, 
        decode((MIN(CASE WHEN q.NIQ = 4976 AND bmr.reponse = 'Aucun'                                          THEN bmr.REPONSE END)), NULL, 'N', 'O') DclPCAucun091,
        decode((MIN(CASE WHEN q.NIQ = 4976 AND bmr.reponse = 'IRM'                                            THEN bmr.REPONSE END)), NULL, 'N', 'O') DclPCIRM092, 
        decode((MIN(CASE WHEN q.NIQ = 4976 AND bmr.reponse = 'Scanner'                                        THEN bmr.REPONSE END)), NULL, 'N', 'O') DclPCScanner093, 
        decode((MIN(CASE WHEN q.NIQ = 4976 AND bmr.reponse = 'SPECT'                                          THEN bmr.REPONSE END)), NULL, 'N', 'O') DclPCSPECT094, 
        decode((MIN(CASE WHEN q.NIQ = 4976 AND bmr.reponse = 'PET'                                            THEN bmr.REPONSE END)), NULL, 'N', 'O') DclPCPET095,
        decode((MIN(CASE WHEN q.NIQ = 4976 AND bmr.reponse = 'Biomarqueurs'                                   THEN bmr.REPONSE END)), NULL, 'N', 'O') DclPCBioMarqueurs096,
        /* -------------------------------------- 9eme Partie -------------------------------------- */
        decode((MIN(CASE WHEN q.NIQ = 4990 THEN decode(bmr.REPONSE,'aucune','AUCUNE','tutelle','TUTELLE','curatelle','CURATELLE','sans information','SI') END)), '', 'SI', 
                MIN(CASE WHEN q.NIQ = 4990 THEN decode(bmr.REPONSE,'aucune','AUCUNE','tutelle','TUTELLE','curatelle','CURATELLE','sans information','SI') END)) DclMesureProtection063
     
    FROM
        BM_TH_S th
        INNER JOIN      PATIENT pat    ON pat.nipatient = th.nipatient
        LEFT OUTER JOIN INFOPAT infpat ON pat.nipatient = infpat.nipatient
        INNER JOIN      EJ_SRV  srv    ON th.niservice  = srv.niservice
        -- Jointures pour les sous-requêtes corrélées
        INNER JOIN BM_TH_S      bmt    ON bmt.nith      = th.nith
        INNER JOIN BM_LIB_S     bml    ON bmt.NITH      = bml.NITH
        INNER JOIN BM_REP_S     bmr    ON bml.NILIB     = bmr.NILIB
        INNER JOIN C_QUESTION   q      ON bml.NIQ       = q.NIQ
     
    WHERE
        th.niquest  = '194' AND                                  -- Identifiant du Questionnaire de référence
        th.retrait  = 'F'   AND                                  -- Etat de la supression logique du document
        srv.retrait = 'F'   AND                                  -- Drapeau de supression de l'enregistrement
        substr(th.dates, 0, 8) = to_char(sysdate-1, 'yyyymmdd')  -- Date du jour 
     
    GROUP BY
        pat.NOM,
        pat.PRENOM,
        pat.SEXE,
        pat.NIP,
        substr(pat.DATENAIS, 1, 4),
        substr(pat.DATENAIS, 5, 2),
        substr(pat.DATENAIS, 7, 2),
        decode(pat.PATRONYME,
                   null, pat.NOM, 
                     '', pat.NOM, 
                     pat.PATRONYME),
        infpat.NUMSECU,
        decode(infpat.NUMSECU, 
                   null, '', 
                     '', '', 
                     substr(infpat.NUMSECU, 6, 2)) ,
        decode(infpat.NUMSECU, 
                   null, '', 
                     '', '', 
                     substr(infpat.NUMSECU, 8, 3)) ,
        decode(srv.NIETABLIS,
                    1, 'MZ',  3, 'MZ',  4, 'MZ',  
                    5, 'MZ',  8, 'MZ',  9, 'MZ', 
                   24, 'MZ', 10, 'TH', 11, 'TH', 
                   12, 'TH', 13, 'TH', 14, 'TH', 
                   15, 'TH', 16, 'TH', 17, 'TH', 
                   18, 'TH', 19, 'TH', 20, 'MZ', 
                   21, 'TH', 22, 'MZ', 23, 'TH', 
                   25, 'TH', 'Autre');
    - Le GROUP BY est correct ?
    - Peut-on vérifier que deux requêtes sont identique ?
    - Peut-on vérifier les performances des deux requêtes ?
    - y'a t-il d'autres amélioration pour simplifier la requête ?

  7. #27
    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
    Je n'ai pas vérifié par rapport à la requête d'origine mais la nouvelle semble correcte.
    Oui, le GROUP BY semble correct puisqu'il reprend les colonnes du SELECT qui ne contiennent pas de fonctions de calcul.

    Est-ce encore simplifiable ? Je ne sais pas.

    Côté performances, testez vous-même la différence entre les deux requêtes sur le même jeu de données.
    S'il y a peu de données, la différence ne sera pas significative mais s'il y en a beaucoup, je parierais pour une victoire de la nouvelle requête.

    Si le résultat de cette requête doit être affiché par une application, j'aurais plutôt récupéré les données davantage en brut et traité l'interprétation dans le langage de programmation de l'application. Cette requête ressemble en effet bigrement à de la cosmétique, ce qui n'est pas le boulot du SGBD.
    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. #28
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    Effectivement c'est de la cosmétique. Mais le code Java qui traite le résultat derrière est très simple

  9. #29
    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
    Ben comme l'explique SQLPro dans son cours SQL, pas sûr du tout que ce soit le bon choix !
    S'il y a très peu de données, ça ne pénalisera pas l'utilisateur mais s'il y a des centaines de milliers de lignes ou encore davantage, il finira par avoir le temps d'aller boire un café avant de voir le résultat.
    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 !

  10. #30
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    c'est une requête qui s'effectue la nuit.
    Je vais voir pour supprimer tous les 'decode' ainsi que les colonnes inutiles.

  11. #31
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    J'en profite pour poser la question, y'a t-il des fonctions/tuto pour faire l'équivalent des decode, substr etc ... en java ?

  12. #32
    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
    DECODE, c'est en quelque sorte un switch. Si telle valeur en entrée alors telle valeur en sortie.
    SUBSTR doit bien avoir son équivalent en Java comme dans n'importe quel autre langage parce que ça fait partie des fonctions texte de base.
    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 !

  13. #33
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    DECODE c'est la vieille version de CASE WHEN THEN ELSE END.
    C'est un simple IF.

  14. #34
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 050
    Points : 9 386
    Points
    9 386
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    C'est bizarre qu'il ne commence à tiquer qu'au dernier alias ! Tu es sûr que tu as bien repris identiquement l'alias de la colonne du SELECT dans le GROUP BY ?
    Quand il y a plusieurs erreurs dans une requête, Oracle signale la dernière erreur, et non la première... C'est surprenant, mais c'est comme ça.



    La dernière requête proposée me paraît optimisée.
    Maintenant, tu as un seul SELECT au lieu de 40 ou 50 SELECT imbriqués.
    Tu as dû diviser le temps de traitement par 5 au minimum, et probablement beaucoup mieux.

    L'étape suivante serait éventuellement d'utiliser les Hints, pour aider Oracle à choisir le bon plan d'exécution, et les bons indexes.
    Mais si Oracle s'en sortait avant, il devrait s'en sortir maintenant.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  15. #35
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    Mon premier objectif est de simplifier la requête pour pouvoir la comprendre et éventuellement la modifier.
    L'optimisation ne m’intéresse pas, cette requête est lancé une fois par jour (la nuit) et prend moins d'une seconde (une dizaine de ligne comme résultat).

  16. #36
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 147
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Juste comme ça : je pense qu'il est impératif de comprendre la requête dans son intégralité AVANT de chercher à la simplifier.

    Sinon, c'est le meilleur moyen de produire des bugs !
    On ne jouit bien que de ce qu’on partage.

  17. #37
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 050
    Points : 9 386
    Points
    9 386
    Par défaut
    Effectivement.
    Et sur cet exemple, la requête de départ était si compliquée... Même si sur tes premiers tests, tu obtiens la même chose avec les 2 requêtes, rien ne garantit que les 2 requêtes soient strictement équivalentes.

    En particulier le cas des données manquantes. si un code Nipatient est présent dans une table mais pas dans l'autre, les résultats sont-ils les mêmes ???

    Éventuellement, construis une base de test avec des jeux de données volontairement tronqués (données manquantes dans la table C_QUESTION par exemple), et vérifie si les 2 requêtes donnent la même chose.
    Et en cas de différence, fais valider par ton 'client' laquelle des 2 requêtes donne le résultat voulu.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  18. #38
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    Concernant la restriction sur la date :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    substr(RDV.DATE_RDV, 1, 8) = to_char(sysdate + 1, 'yyyymmdd')
    est-ce la bonne manière de faire ? Comme récupérer sur plusieurs jours ? Avec un BETWEEN ?

  19. #39
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Non ce n'est pas la bonne manière de faire.
    Quel est le type de la colonne DATE_RDV ?

  20. #40
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Points : 262
    Points
    262
    Par défaut
    DATA_TYPE : NUMBER(12, 0)

Discussions similaires

  1. Aide pour Simplifier/optimiser une requête SQL
    Par bubu06 dans le forum Requêtes
    Réponses: 3
    Dernier message: 10/05/2012, 18h25
  2. [MySQL] Simplifier une requête sql et affichage dans un tableau
    Par Debutant10 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 01/05/2012, 14h36
  3. [MySQL] Simplifier une requête SQL
    Par maestro982 dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 23/05/2010, 13h26
  4. [SQL] Simplifier une requête SQL ?
    Par renaud26 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 29/04/2006, 13h50
  5. Utilisation de MAX dans une requête SQL
    Par Evil onE dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/06/2004, 18h38

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