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

SQL Oracle Discussion :

Fonctionnement d'une requête


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 30
    Par défaut Fonctionnement d'une requête
    Bonjour à tous,

    débutant en SQL, j'ai acquis les bases il y a de cela quelques temps et j'ai vraiment du mal à comprendre le fonctionnement de la requête ci-dessous.

    Ayant retiré toutes les parties répétitives ou comprises, la requête n'est pas fonctionnelle et des tables qui n'existent pas sont utilisées. Mais peu importe car mon but est de comprendre le fonctionnement SQL et pas la requête en elle même.

    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
     
    SELECT   CONTRAT_REF AS "Reference",
             DECODE(TYPECONTR_REF, 'C', CONTRAT_REF || ' - Contrat principal du site ' || (SELECT SITE_NOM FROM SITE, PDS WHERE PDS_NOMSITE = SITE_REF AND PDS_REF = CONTRAT_REFPDS), FNGETLIBELLECONTRAT(CONTRAT_REF)) AS "Libelle",
             INTERLOC_CIVIL || ' ' || INTERLOC_NOM || ' ' || INTERLOC_PRENOM AS "Interlocuteur",
             TRUNC(ENTPIEDFAC_DATEPRCHREL) AS "DateProchaineReleve"
    FROM     CONTRAT,
             REGROUPADMIN,
             (
                SELECT MAX(CONTRATFAC_NUMFAC) CONTRATFAC_NUMFAC, CONTRAT_REF CONTRATFAC_REFCONTRAT
                FROM
                (
                SELECT CONTRATFAC_NUMFAC, 
                FROM   CONTRAT
                WHERE  CONTRAT_REFCLIENT = :Reference
                AND    CONTRATFAC_REFCONTRSERV = CONTRAT_REF
                UNION
                SELECT CONTRAT_REF
                FROM   CONTRATFAC,
                WHERE  CONTRAT_REFCLIENT = :Reference
                AND    CONTRATFAC_REFCONTRSERV = AVENANTCONTR_REFCONTRINI
                )
                GROUP BY CONTRAT_REF
              ) CONTRATFAC,
    WHERE    CONTRAT_REF IN (
        SELECT DECODE(AVENANTCONTR_REFCONTRINI, NULL, CONTRAT_REF, AVENANTCONTR_REFCONTRNEW)
        FROM   CONTRAT,
               V_DERNAVENANTCONTR
        WHERE  CONTRAT_REFCLIENT = :Reference
        AND    AVENANTCONTR_REFCONTRNEW (+) = CONTRAT_REF
        AND    NOT EXISTS
        (
            SELECT 1
            FROM   AVENANTCONTR
            WHERE  AVENANTCONTR_REFCONTROLD = CONTRAT_REF
            AND    AVENANTCONTR_REFCONTROLD <> AVENANTCONTR_REFCONTRNEW
        )
        UNION
        SELECT DECODE(AVENANTCONTR_REFCONTRINI, NULL, CONTRAT_REF, AVENANTCONTR_REFCONTRNEW)
        FROM   CONTRAT,
               COMPOREGROUP,
               REGROUP,
               V_DERNAVENANTCONTR
        WHERE  REGROUP_REFPAYEUR = :Reference
        AND    COMPOREGROUP_IDFREGROUP = REGROUP_IDF
        AND    CONTRAT_REF = COMPOREGROUP_REFCONTRAT
        AND    AVENANTCONTR_REFCONTRNEW (+) = CONTRAT_REF
        AND    COMPOREGROUP_REPARTPAIEMT > 0
        AND    NOT EXISTS
        (
            SELECT 1
            FROM   AVENANTCONTR
            WHERE  AVENANTCONTR_REFCONTROLD = CONTRAT_REF
            AND    AVENANTCONTR_REFCONTROLD <> AVENANTCONTR_REFCONTRNEW
        )
    )
    AND      PDS_REF = CONTRAT_REFPDS
    AND      TARIFENERG_CODETARIFDNN (+) = CONTRAT_CODETARIFDNN
     
    ORDER BY CONTRAT_ETAT, CONTRAT_REF

    Je met ici tout ce que je crois avoir compris ainsi que mes questions !

    Le SELECT me permet de "sélectionner le nom de cette colonne" AS "le nom que je lui donne" FROM "la table d'ou elle provient" WHERE "condition permettant de filtrer et retourner les lignes de la colonne en question" AND "condition2" ORDER BY "triage de l'ordre des lignes retournées".

    DECODE correspond à DECODE(variable, valeur1, retour1, valeur2, retour2, retourSinon) mais je n'arrive pas à comprend la syntaxe particulière utilisée ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     DECODE(TYPECONTR_REF, 'C', CONTRAT_REF || ' - Contrat principal du site ' || (SELECT SITE_NOM FROM SITE, PDS WHERE PDS_NOMSITE = SITE_REF AND PDS_REF = CONTRAT_REFPDS), FNGETLIBELLECONTRAT(CONTRAT_REF)) AS "Libelle"
    Si TYPECONTR_REF vaut C (mais ici c'est quoi qui vaut C ?? Le nom de la colonne TYPECONTR_REF ?) on retourne CONTRAT_REF ou ' - Contrat principal du site ' ou un SELECT, puis je suppose que FNGETLIBELLECONTRAT(CONTRAT_REF) correspond au retourSinon, donc là ici la colonne qui sera nommé Libelle correspondra soit à ça soit à ça en fonction du case je suppose.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
             INTERLOC_CIVIL || ' ' || INTERLOC_NOM || ' ' || INTERLOC_PRENOM AS "Interlocuteur",
    Ici à quel moment l'un ou l'autre change ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     TRUNC(ENTPIEDFAC_DATEPRCHREL) AS "DateProchaineReleve",
    Ici on arrondie, si par exemple la date est 12.5 on met 12


    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
     
             FROM     CONTRAT,
             REGROUPADMIN,
             (
                SELECT MAX(CONTRATFAC_NUMFAC) CONTRATFAC_NUMFAC, CONTRAT_REF CONTRATFAC_REFCONTRAT
                FROM
                (
                SELECT CONTRATFAC_NUMFAC, 
                FROM   CONTRAT
                WHERE  CONTRAT_REFCLIENT = :Reference
                AND    CONTRATFAC_REFCONTRSERV = CONTRAT_REF
                UNION
                SELECT CONTRAT_REF
                FROM   CONTRATFAC,
                WHERE  CONTRAT_REFCLIENT = :Reference
                AND    CONTRATFAC_REFCONTRSERV = AVENANTCONTR_REFCONTRINI
                )
                GROUP BY CONTRAT_REF
              ) CONTRATFAC,
    Ici on a une sous-requête qui correspond à une vue ajoutée dans le FROM ?
    Nommé CONTRATFAC, elle correspond au troisième appel de FROM elle effectue un SELECT et dans ce SELECT on effectue un FROM qui a également besoin d'une sous requête afin de faire une union (donc il fusionnent les résultats des deux colonnes), ensuite un GROUP BY de la première sous-requête est effectué puis le résultat se retrouve dans CONTRATFAC. Cependant, je ne comprend pas le :Reference car ici à ma première ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CONTRAT_REF AS "Reference",
    j'utilise le terme Reference, cela signifie t'il que partout ou j'écrit :Reference c'est comme si je référençai la colonne CONTRAT_REF ?

    Et pour ce qui est de la suite de la requête je vois à peu près le genre de condition que l'on retrouve mais je pense que je n'ai pas besoin de me pencher trop dessus car c'est assez spécifique au table en question et que les conditions sont amené à changer en fonction de chaque requête, c'est pourquoi je préfère d'abord bien comprendre le fonctionnement de base de Oracle.

    N'importe quelle aide serai appréciable, peu importe si elle répond à mes questions, tant qu'elle me permet de mieux comprendre le fonctionnement, je vous en serai redevable, merci énormément d'avance à vous pour votre aide !

    Cordialement

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 133
    Par défaut
    Quelques réponses à tes questions :
    Citation Envoyé par LEROYLudovic Voir le message
    DECODE correspond à DECODE(variable, valeur1, retour1, valeur2, retour2, retourSinon) mais je n'arrive pas à comprend la syntaxe particulière utilisée ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     DECODE(TYPECONTR_REF, 'C', CONTRAT_REF || ' - Contrat principal du site ' || (SELECT SITE_NOM FROM SITE, PDS WHERE PDS_NOMSITE = SITE_REF AND PDS_REF = CONTRAT_REFPDS), FNGETLIBELLECONTRAT(CONTRAT_REF)) AS "Libelle"
    Si TYPECONTR_REF vaut C (mais ici c'est quoi qui vaut C ?? Le nom de la colonne TYPECONTR_REF ?)
    C'est la valeur contenue dans la colonne TYPECONTR_REF qui est comparée à 'C'
    Citation Envoyé par LEROYLudovic Voir le message
    on retourne CONTRAT_REF ou ' - Contrat principal du site ' ou un SELECT, puis je suppose que FNGETLIBELLECONTRAT(CONTRAT_REF) correspond au retour Sinon, donc là ici la colonne qui sera nommé Libelle correspondra soit à ça soit à ça en fonction du case je suppose.
    L'opérateur || en SQL effectue la concaténation de deux chaînes de caractères. Il ne faut pas le confondre avec l'opérateur || dans d'autres langages de programmation qui effectue un OU logique entre deux valeurs booléennes. En SQL le OU logique s'exprime par l'opérateur OR.
    Citation Envoyé par LEROYLudovic Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     TRUNC(ENTPIEDFAC_DATEPRCHREL) AS "DateProchaineReleve",
    Ici on arrondie, si par exemple la date est 12.5 on met 12
    On n'arrondit pas, on tronque pour ne garder que la date en supprimant les heures.
    Citation Envoyé par LEROYLudovic Voir le message
    Cependant, je ne comprend pas le :Reference car ici à ma première ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CONTRAT_REF AS "Reference",
    j'utilise le terme Reference, cela signifie t'il que partout ou j'écrit :Reference c'est comme si je référençai la colonne CONTRAT_REF ?
    :Reference correspond à une variable qui est définie plus haut dans le script, avant le début de la requête.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 202
    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 202
    Par défaut
    Sur le UNION :
    Tu as une première requete RQ1 qui renvoie 1 colonne, et par exemple 100 lignes
    Tu as une seconde requete RQ2 qui renvoie aussi 1 colonne , et par exemple 80 lignes
    Et quand tu fais l'UNION de ces 2 trucs, tu auras 1 colonne et par exemple 170 lignes ( S'il y a des lignes en double dans RQ1, ou en double dans RQ2, ou en commun entre RQ1 et RQ2, tout cela sera dédoublonné, et donc tu auras souvent moins de lignes que 100+80)
    Et pour faire un UNION entre 2 requêtes, il faut ques les 2 requêtes renvoient le même nombre de colonnes, et en plus, il ne faut pas mélanger des colonnes de type Nombre avec des colonnes de type Date par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Select Nombre, date from table1
    Union 
    Select Nombre , date from table2   --> Ok
     
     
    Select Nombre from table1
    Union 
    Select date from table2   --> Pas ok

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 30
    Par défaut
    merci beaucoup, cela m'as permis de mieux comprendre .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FROM   SITE, 
        TYPESITE, 
        UTILIS "Responsable",
        UTILIS "ChargeClientele"
    AND    "ChargeClientele".UTILIS_REF (+) = SITESUPP_CLIENTELE
    AND    SITE_REF = :Reference
    Je n'ai pas bien compris. Ici on sélectionne les colonnes des tables SITE TYPESITE et UTILIS mais que signifie le "Responsable" et le "ChargeClientele" à coté de UTILIS, je suppose que c'est ce qui différencie les deux utilisations de la même table et c'est que l'on appel tel ou tel chose de cette table (From la colonne Responsable et ChargeClientele de la table UTILISE ??)

    et pour ce qui est des deux conditions suivantes, sur la première nous effectuons une jointure externe entre la colonne ChargeClientele de la table UTILIS_REF et on le MERGE avec la table SITESUPP_CLIENTELE ??
    La dernière condition signifie bien que si la valeur de la variable référence n'est pas égal a SITE_REF alors la requête ne renvoie rien ?

    Merci encore de m'éclairer et merci énormément pour votre aide.

  5. #5
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 202
    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 202
    Par défaut
    Non. Il y a beaucoup d'erreurs dans ce que tu écris.

    A priori, dans la table UTILIS, il n'y a pas de colonne RESPONSABLE ni CHARGECLIENTELE.

    A mon avis, on est dans un truc comme ça :
    On a une table UTILIS, avec tous les salariés de l'entreprise. Cette table a essentiellement 2 colonnes, une colonne identifiant Id_employe (un n° d'employé) et une colonne NOM ( le nom+prénom de l'employé)
    Pour chaque contrat,le contrat doit être validé par un RESPONSABLE et par un chargé de Clientèle. Dans la Table CONTRAT, on a donc 1 colonne Id_Contrat, une colonne Id_Responsable, et une colonne Id_Chargeclientele.

    Et on veut afficher Pour chaque contrat le n° de contrat, et le nom des 2 personnes en question.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select id_contrat , u1.nom_employe as nom_responsable , u2.nom_employe as nom_charge_clientele
    from contrat c, utilis u1, utilis u2 
      where u1.id_employe = c.id_responsable
         and u2.id_employe = c.id_chargeClientele

    "ChargeClientele".UTILIS_REF : Dans l'ordre, c'est nom_table.nom_colonne. Donc c'est la colonne UTILIS_REF de la table ChargeClientele. Ici, ChargeClientele n'est pas vraiment une table c'est un alias ( ou un synonyme si tu préfères) pour la table UTILIS.
    Dans ton message, tu inversais donc TABLE et COLONNE. Et c'est une grosse erreur.
    Idem SITESUPP_CLIENTELE n'est pas une table ; c'est une colonne de la table SITE, ou de la table TYPESITE.
    Le type qui a écrit la requete n'a pas été sympa. Lui, il sait que la colonne SITESUPP_CLIENTELE vient de telle table. Le moteur ORACLE aussi sait de quelle table vient cette colonne, car il n'y a pas ambiguité, mais le relecteur ne sait pas.
    La bonne pratique, c'est de toujours préfixer les colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FROM   SITE S, 
        TYPESITE TS, 
        UTILIS "Responsable",
        UTILIS "ChargeClientele"
    AND    "ChargeClientele".UTILIS_REF (+) = S.SITESUPP_CLIENTELE
    AND    S.SITE_REF = :Reference

    Dernier point, plus anecdotique, ou plus sémantique. Tu dis : La dernière condition signifie bien que si la valeur de la variable référence n'est pas égal a SITE_REF alors la requête ne renvoie rien ?
    SITE_REF a plein de valeurs. Dans ta table SITE ou TYPE_SITE, tu as plein de lignes, et potentiellement plein de valeurs de SITE_REF différentes.
    Si tu as 1000 lignes dans SITE ou TYPE_SITE ( le rôle respectif de ces 2 tables n'est pas clair avec ce que tu montres), on n'est pas dans une situation où la requête renvoie TOUT ou RIEN.
    Si tu as 1000 lignes dans SITE ou TYPE_SITE, la requête va renvoyer uniquement 30 ou 50 lignes par exemple , elle va renvoyer uniquement les lignes pour lesquelles SITE_REF vaut la valeur demandée.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 30
    Par défaut
    Tes explications sont très claires, je peut sentir en toi un grand pédagogue ainsi qu'une grande maîtrise du langage le tout couplé à un sens logique sur-développer car tu arrives à imaginer des situations entre les tables et c'est vraiment ce qu'il faut que j'arrive à faire. Merci !

  7. #7
    Membre Expert
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    2 005
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 2 005
    Par défaut
    Citation Envoyé par LEROYLudovic Voir le message
    Tes explications sont très claires, je peut sentir en toi un grand pédagogue ainsi qu'une grande maîtrise du langage le tout couplé à un sens logique sur-développer car tu arrives à imaginer des situations entre les tables et c'est vraiment ce qu'il faut que j'arrive à faire. Merci !
    J'espère qu'un jour on dira la même chose de moi

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

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