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 :

[8i] Jointure externe sur sous-requête avec max()


Sujet :

SQL Oracle

  1. #1
    Membre du Club Avatar de Devether
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 66
    Points : 54
    Points
    54
    Par défaut [8i] Jointure externe sur sous-requête avec max()
    Bonjour,

    J'ai un petit problème de jointure externe quand j'utilise le (+) sur une sous requête. Le problème c'est que dans cette sous requête j'ai un MAX() qui ne m'affiche pas de valeur s'il vaut 0.

    Je simplifie mon schéma pour une meilleur compréhension :

    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
     
    DOSSIERS
    +-------+---------------------+---------------+
    |  DID  |       DATE_DEBUT    |  DESCRIPTION  |
    +-------+---------------------+---------------+
    |  0001 | 2008-10-20 10:32:28 |  ...          |
    |  0002 | 2008-10-20 11:23:31 |  ...          |
    +-------+---------------------+---------------+
     
    GESTION_DOSSIERS
    +-------+---------------------+---------------+------------+
    |  DID  |       DATE_OPER     |  STATUT       |  COMPTEUR  |
    +-------+---------------------+---------------+------------+
    |  0001 | 2008-10-20 10:32:28 |  Escaladé     |    1       |
    |  0001 | 2008-10-20 14:19:03 |  En cours     |    2       |
    |  0001 | 2008-10-20 15:01:47 |  Escaladé     |    3       |
    +-------+---------------------+---------------+------------+
    Avec ceci, pour récupérer le dernier STATUT j'aurais tendance à faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT GD.STATUT
    FROM DOSSIERS D,
         GESTION_DOSSIERS GD
    WHERE D.DID = GD.DID(+) AND
          GD.COMPTEUR = (   SELECT MAX(COMPTEUR)
                               FROM GESTION_DOSSIERS
                               WHERE DID = D.DID
          );
    Mais là pour le DOSSIER.DID = 0002 il ne me retourne pas de ligne car il n'existe pas dans GESTION_DOSSIERS.

    J'ai pensé mettre ...GD.COMPTEUR (+)= ( SELECT MAX(COMPTEUR)...
    mais j'obtiens l'erreur :
    => ORA-01799: une colonne ne peut être jointe extérieurement à une sous-requête
    Donc là je sèche car j'ai besoin de récupérer d'autres infos en plus du STATUT même si le DID n'existe pas dans GESTION_DOSSIERS, mais l'enregistrement n'est tout simplement pas renvoyé.

    Merci d'avance pour votre aide,
    Devether

  2. #2
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Et ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT GD.STATUT
    FROM DOSSIERS D,
         (SELECT MAX(COMPTEUR) COMPTEUR, STATUT, DID
                               FROM GESTION_DOSSIERS
        GROUP BY DID, STATUT) GD
    WHERE D.DID = GD.DID(+);

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 383
    Points
    18 383
    Par défaut
    Il vous faut modifier votre condition pour ne pas exclure les nulls :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AND (GD.COMPTEUR = (SELECT MAX(COMPTEUR)
                       FROM GESTION_DOSSIERS
                       WHERE DID = D.DID)
      OR GD.COMPTEUR IS NULL)
    Les parenthèses sont essentielles ici.

  4. #4
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    en réfléchissant, ma proposition est complétement stupide, t'auras la même erreur

    Waldar -> plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    OR NOT EXISTS (SELECT 1
                       FROM GESTION_DOSSIERS
                       WHERE DID = D.DID)

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 383
    Points
    18 383
    Par défaut
    Pourquoi reparcourir gestion_dossier puisqu'elle est déjà dans le from initial ? Ce sera plus coûteux qu'un simple isnull !

  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    le problème n'est pas que le compteur est null mais qu'il n'existe pas

    il ne me retourne pas de ligne car il n'existe pas dans GESTION_DOSSIERS.
    si compteur est nulle c'est qu'il y a une ligne... ce qui n'est pas le problème posé

    Par contre, je ne comprends pas l'idée... il faut afficher null quand il n'y a pas de ligne dans GD qui correspond à un dossier ?

    Devether, tu veux pas être plus clair sur le besoin STP ?

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 383
    Points
    18 383
    Par défaut
    Citation Envoyé par orafrance Voir le message
    le problème n'est pas que le compteur est null mais qu'il n'existe pas
    C'est la même chose, comme le prouve cet exemple :
    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
    WITH dossiers AS
        (
        select 1 did, to_date('20/10/2008 10:32:28', 'dd/mm/yyyy hh24:mi:ss') dt_debut from dual union
        select 2, to_date('20/10/2008 11:23:31', 'dd/mm/yyyy hh24:mi:ss') from dual
        ),
        gestion_dossiers AS
        (
        select 1 did, to_date('20/10/2008 10:32:28', 'dd/mm/yyyy hh24:mi:ss') dt_ope, 'Escaladé' statut, 1 compteur from dual union
        select 1, to_date('20/10/2008 14:19:03', 'dd/mm/yyyy hh24:mi:ss'), 'En cours', 2 from dual union
        select 1, to_date('20/10/2008 15:01:47', 'dd/mm/yyyy hh24:mi:ss'), 'Escaladé', 3 from dual
        )
    SELECT
        D.DID,
        GD.STATUT
    FROM
        DOSSIERS D,
        GESTION_DOSSIERS GD
    WHERE
        D.DID = GD.DID(+)
    AND (GD.COMPTEUR = (SELECT MAX(COMPTEUR)
                       FROM GESTION_DOSSIERS
                       WHERE DID = D.DID)
      OR GD.COMPTEUR IS NULL)
    ne fonctionnera pas en Oracle 8

  8. #8
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    ha oui... j'pensais pas que ça fonctionnerait

    ça veut dire qu'Oracle interprête la jointure externe avant... t'es sûr que selon le plan d'exécution c'est pas susceptible de poser problème ?

  9. #9
    Membre du Club Avatar de Devether
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 66
    Points : 54
    Points
    54
    Par défaut Merci
    Citation Envoyé par orafrance Voir le message
    Par contre, je ne comprends pas l'idée... il faut afficher null quand il n'y a pas de ligne dans GD qui correspond à un dossier ?

    Devether, tu veux pas être plus clair sur le besoin STP ?
    En fait, il faut imaginer qu'il y a d'autres jointures sur d'autres tables qui contiennent des infos sur d'autres choses (utilisateur, type du dossier, ...). Je veux ces infos même si GESTION_DOSSIERS ne contient aucune info sur un dossier.

    Citation Envoyé par Waldar Voir le message
    Il vous faut modifier votre condition pour ne pas exclure les nulls :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AND (GD.COMPTEUR = (SELECT MAX(COMPTEUR)
                       FROM GESTION_DOSSIERS
                       WHERE DID = D.DID)
      OR GD.COMPTEUR IS NULL)
    Les parenthèses sont essentielles ici.
    En effet les parenthèses sont essentielles car j'avais pourtant testé quelque chose du même genre qui ne marchait pas. En toute logique je n'avais pas du mettre les parenthèses ou il fallait car avec cette méthode la requête me renvoi bien tous les enregistrements.

    Un grand merci car j'y suis depuis hier matin.

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

Discussions similaires

  1. Jointure externe sur sous rapport
    Par ALLODREN dans le forum iReport
    Réponses: 2
    Dernier message: 03/02/2014, 23h54
  2. Jointures Externes sur sous requête
    Par LeTaz dans le forum Langage SQL
    Réponses: 2
    Dernier message: 20/05/2008, 16h58
  3. [MySQL] Jointure externe sur requête avec MySQL
    Par ginkas31 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 01/02/2008, 11h02
  4. Jointure externe sur une sous-requête
    Par pgentils dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/01/2008, 09h34
  5. [DB2] Problèmes avec une Jointure externe sur des vues
    Par treivse dans le forum Langage SQL
    Réponses: 6
    Dernier message: 11/07/2006, 11h42

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