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

DB2 Discussion :

Sous-requête corrélée, clause FROM et jointures


Sujet :

DB2

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2017
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2017
    Messages : 38
    Points : 38
    Points
    38
    Par défaut Sous-requête corrélée, clause FROM et jointures
    Bonjour,

    J'ai rédigé une requête dans laquelle je fais appel à une sous-requête correlée dans la clause FROM et j'ai un message d'erreur m'indiquant que la colonne utilisée provenant de la requête parent est introuvable, et je n'arrive pas à en déterminer la cause, ni à trouver une syntaxe alternative. Je fais donc appel à vos connaissances.

    Voici le problème.
    Je dois sélectionner, pour chaque entrée d'une table CSP (condition spéciale permanente), le tarif d'achat qui était en vigueur au moment de sa création.
    Chaque tarif est daté et propre à un article.
    L'idée est d'obtenir le tarif dont la date de création est la plus proche et inférieure ou égale à la date de création de chaque CSP.

    Et voici la requête (largement simplifiée pour l'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
    24
    25
    26
    27
    28
    29
    SELECT
    CSP.CSCODE, -- Code Client
    CSP.CSART, -- Code Article
    CSP.CSDTDB, -- Date début CSP
    CSP.CSDTFN, -- Date fin CSP
    CSP.CSPRX, -- Prix de la CSP
    T1.TADATE, -- Date tarif
    T1.TAPRR -- Tarif achat
     
    FROM GIAM10.CSP CSP
     
    INNER JOIN (
    	SELECT
    	TARIF.TAART,
    	MAX(TARIF.TADATE) AS MAXDATE
     
    	FROM
    	GIAM95.TARIF TARIF
     
    	WHERE
    	TARIF.TADATE <= CSP.CSDTDB
     
    	GROUP BY
    	TARIF.TAART) T2
    ON CSP.CSART = T2.TAART
     
    INNER JOIN GIAM95.TARIF T1
    ON (T1.TAART = T2.TAART
    	AND T1.TADATE = T2.MAXDATE)
    Le message d'erreur est le suivant : "La colonne ou la variable globale CSDTDB est introuvable."
    A noter que si je remplace CSP.CSDTDB dans la sous-requête T2 par une date fixe, la requête s'exécute bien.

    Pouvez-vous m'aider ?

    Je vous remercie.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 55
    Points : 75
    Points
    75
    Par défaut
    Bonjour,

    Pour que CSP.CSDTB soit dispo dans la sous requête il faut utiliser le mot clé LATERAL, ainsi la requête T2 sera exécuté pour chaque CSP, et non globalement puis jointe à CSP, le GROUP BY est alors superflu autant utiliser CSART dans le where et faire un produit cartésien.

    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
     
    SELECT
      csp.cscode, -- Code Client
      csp.csart,  -- Code Article
      csp.csdtdb, -- Date début CSP
      csp.csdtfn, -- Date fin CSP
      csp.csprx,  -- Prix de la CSP
      t1.tadate,  -- Date tarif
      t1.taprr    -- Tarif achat
    FROM  giam10.csp csp
      CROSS JOIN LATERAL (
        SELECT
          max(tarif.tadate) AS maxdate
        FROM  giam95.tarif tarif
         WHERE  tarif.taart = csp.csart AND tarif.tadate <= csp.csdtdb
      ) as t2
      INNER JOIN giam95.tarif t1 ON t1.taart = t2.taart AND t1.tadate = t2.maxdate
    Après au niveau des perf ça risque de pas être fantastique, TARIF est forcément lu plusieurs fois, et s'il est possible d'avoir deux TARIF à la même TADATE alors la requête renvoi deux ligne pour une CSP.
    Si j'ai bien compris il s'agit d'avoir le dernier tarif avant la début de la CSP du coup je ferais la liste des CSP avec les TARIF applicables, en leur donnant un numéro dans l'ordre descendant de la date, puis choisirais ceux qui ont le numéro 1

    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
     
    SELECT
      csart,
      csdtdb,
      csdtfn,
      csprx,
      tadate,
      taprr
    FROM   (
      SELECT     csp.cscode, -- Code Client
        csp.csart,  -- Code Article
        csp.csdtdb, -- Date début CSP
        csp.csdtfn, -- Date fin CSP
        csp.csprx,  -- Prix de la CSP
        t1.tadate,  -- Date tarif
        t1.taprr    -- Tarif achat,
        ROWNUMBER() OVER(PARTITION BY csart ORDER BY t1.tadate desc) seq
      FROM  giam10.csp csp
        INNER JOIN giam95.tarif t1 ON t1.taart = csp.csart
      WHERE  tadate <= csp.csdtdb
      ) AS tarifs_applicables
    WHERE  seq = 1

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2017
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2017
    Messages : 38
    Points : 38
    Points
    38
    Par défaut
    Bonjour vazymimil,

    Je te remercie pour ta réponse.
    Elle est pleine de bonnes informations.

    J'ai utilisée ta seconde méthode en partitionnant ma table et cela fonctionne à merveille. Pas de problème en terme de performance non plus.

    Je marque le sujet comme résolu.

    Bàv,

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

Discussions similaires

  1. UPDATE avec sous-requête corrélée
    Par Oishiiii dans le forum Requêtes
    Réponses: 0
    Dernier message: 04/09/2009, 09h58
  2. Sous-requête dans un FROM ou table temporaire
    Par dachman dans le forum Développement
    Réponses: 7
    Dernier message: 02/12/2008, 12h41
  3. Sous-requête corrélée ne fonctionne pas
    Par Sylvain74 dans le forum Access
    Réponses: 5
    Dernier message: 19/09/2008, 08h35
  4. Sous requête dans un FROM en HQL
    Par mastamx dans le forum Hibernate
    Réponses: 1
    Dernier message: 20/05/2008, 14h54
  5. [connect by] Sous-requêtes corrélées
    Par raj dans le forum SQL
    Réponses: 2
    Dernier message: 27/07/2007, 15h49

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