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 :

"fetch first 1 rows only" dans un "Left Join"


Sujet :

DB2

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 63
    Points : 35
    Points
    35
    Par défaut "fetch first 1 rows only" dans un "Left Join"
    Bonjour à tous,

    j'ai une requete SQL avec beaucoup de jointures de type left pour compléter les données d'une première série de tables liées par inner join...

    Ca marche très bien sauf que dans une des tables jointes par left join, je constate que je peux avoir plusieurs doublons. je voudrais limiter à la toute première occurrence pour ne pas modifier le vrai nombre de ligne provenant des tables liées en inner join.

    Mon explication n'est pas terrible, désolé

    Pour être plus clair, disons que j'ai les tables suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    T1(id, libelle)={1, 'toto'; 2, 'tptp'; ... }, 
    T2(id, libelle)={1, 'tata'; 2, 'tbtb'; ... },
    T3(id, libelle)={1, 'txtx'; 1, 'tyty; 3, 'tztz'; ...}

    je veux lier T1, T2 et T3 pour obtenir un tableau qui donne une seule ligne par T1.ID (où T3.ID ne va pas me créer un doublon car id non unique) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1, toto, tata, txtx
    2, tptp, tbtb, tztz
    ...
    > Je veux volontairement perdre tyty par exemple.

    Si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * 
    FROM T1 INNER JOIN T2 ON T1.ID=T2.ID
                 LEFT OUTER JOIN T3 ON T1.ID=T3.ID
    > je recois 2 lignes avec id = 1 donc pas bon.

    Pour limiter à une seule ligne de résultat je connais cette syntaxe mais qui ne peut s'appliquer qu'après un where :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT ID FROM T3 WHERE ID=1 fetch first 1 rows only
    > il faudrait que je puisse appliquer cette directive directement à l'intérieur de la jointure.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    LEFT OUTER JOIN T3 ON T1.ID=T3.ID  (???que mettre??)
    ...
    voilà... c'est pas simple à expliquer J'espère que vous comprenez.

    Merci de votre aide,

    Nico

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,

    2 solutions, qui passent par une sous-requete :

    un group by : http://sqlpro.developpez.com/cours/sqlaz/ensembles/


    utiliser une fonction de fenetrage : http://publib.boulder.ibm.com/infoce...2Fr0023461.htm

  3. #3
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 56

    Informations forums :
    Inscription : Juin 2008
    Messages : 154
    Points : 225
    Points
    225
    Par défaut
    Bonjour,

    Si tu te moques de savoir quel libellé tu récupèreras dans T3, tu peux tout simplement te servir de MIN ou de MAX. Ca donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT T1.ID, T1.LIB, T2.LIB, MIN(T3.LIB)
    FROM T1
    JOIN T2 ON T1.ID = T2.ID
    LEFT JOIN T3 on T1.ID = T3.ID
    GROUP BY T1.ID, T1.LIB, T2.LIB
    Bonne utilisation

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 63
    Points : 35
    Points
    35
    Par défaut
    Bonjour,

    Un grand merci pour vos aides et suggestions !

    Mais je suis toujours en bataille avec ma requête SQL

    Sur vos conseils j'ai su résoudre le problème exprimé. Mais je me rends compte que j'ai un autre problème qui m’empêche d'arriver au résultat souhaité. Je m'explique...

    Je crois comprendre que je dois faire une requête encapsulée dans la clause FROM de ma requête principale pour filtrer la table T3 avant de la joindre aux autres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * 
    FROM T1 INNER JOIN T2 ON T1.ID=T2.ID
    LEFT OUTER JOIN (requête SQL filtrage T3) T3 ON T1.ID=T3.ID
    requête SQL filtrage T3 sert à rendre unique la colonne T3.ID :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM (
                SELECT Id, Libelle, ROW_NUMBER() OVER (partition by Id) AS ROWID
                FROM T3
                GROUP BY Id, Libelle
    	) T3 
    WHERE ROWID = 1
    Ceci fait ce que je demandais dans mon post...

    Maintenant, mon nouveau problème : je ne peux pas supprimer n'importe quel tuple. Ma clause Where ROWID = 1 fonctionne merveilleusement bien, mais il faudrait que je tienne compte d'un second Id dans T3, disons Id2.

    Je me demande comment faire mon filtre dans ce cas? Il faudrait filtrer T3 avec un clause WHERE ou Id2 serait égal à une donnée qui vient de la requête principale... Je n'y vois plus très clair...

    Merci de vos conseils,

    Nico

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 63
    Points : 35
    Points
    35
    Par défaut
    J'y suis arrivé...

    dans le résultat de ma sous requête, j'affiche le numéro de ligne, le id2 et je génère le numéro de ligne sur id + id 2 ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ROW_NUMBER() OVER (partition by Id || Id2) AS ROWID
    Dans la jointure de la requête principale, je fais le ON T3.id2 = mon_id et T3.rowid=1. du coup, la sous requête est filtrée par mon ID2 et je ne reçois qu'une unique ligne (même s'il y en avait plusieurs dans la T3).

    ça me parait maintenant évident....

    Mais j'ai du manger mon clavier pour y arriver

    Merci pour vos aides.

    Nico

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT *
    FROM (
                SELECT Id, Libelle, ROW_NUMBER() OVER (partition by Id) AS ROWID
                FROM T3
                GROUP BY Id, Libelle
    	) T3 
    WHERE ROWID = 1
    A quoi sert le group by ?
    Pour moi il ne sert à rien, à part forcer le SGBD à faire une aggrégation.



    ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ROW_NUMBER() OVER (partition BY Id || Id2) AS ROWID
    Faites plutot ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ROW_NUMBER() OVER (partition BY Id, Id2) AS ROWID
    vous pouvez aussi rajouter un order by après le partition by.

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

Discussions similaires

  1. [Débutant] Afficher une table liée dans un report (left join)
    Par DaCoolG dans le forum ASP.NET MVC
    Réponses: 0
    Dernier message: 11/06/2015, 16h33
  2. FETCH FIRST x ROWS ONLY
    Par mcralcv dans le forum DB2
    Réponses: 1
    Dernier message: 05/05/2012, 15h45
  3. FETCH FIRST xx ROWS ONLY
    Par SuperWaza dans le forum DB2
    Réponses: 5
    Dernier message: 25/09/2009, 09h59
  4. Réponses: 6
    Dernier message: 23/01/2007, 10h17
  5. Modification d'un texte dans une fenetre "d'erreur"
    Par PAUL87 dans le forum Access
    Réponses: 8
    Dernier message: 21/10/2005, 13h12

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