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 :

Condition supplémentaire de sélection sur deux enregistrements


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2019
    Messages : 4
    Par défaut Condition supplémentaire de sélection sur deux enregistrements
    Bonjour à toutes et tous

    Désolé pour le titre très flou, je n'ai pas su décrire correctement mon besoin. Je vais donc passer par un exemple :

    Je dispose de 3 tables (SQL Server) et des données suivantes :

    Table A
    Table B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IDb, IDa, ordre, deb, fin
    17, 7, 1, faux, vrai
    18, 7, 2, faux, vrai
    19, 7, 3, faux, faux
    Table C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IDc, IDb, IDa
    27, 18, 7
    La requête actuelle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT B.IDb, B.ordre, A.titre
    FROM A, B, C
    WHERE B.IDa = A.IDa AND B.IDb = C.IDb
    Résultat actuel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IDb, ordre, titre
    18, 2, toto
    Je souhaite rajouter une condition :

    Si l'enregistrement de B (ici le 18) a son champ fin = vrai et que l'enregistrement suivant (ici le 19) a son champ deb = faux alors renvoyer ce dernier enregistrement (soit le 19). Dans le cas contraire, même comportement que la requête actuelle (donc le 18). Soit :

    Résultat souhaité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IDb, ordre, titre
    19, 3, toto
    Question : comment modifier ma requête pour rajouter cette condition ?

    Merci d'avance à tous.

  2. #2
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 363
    Par défaut
    Bonjour,
    Il faut ajouter une jointure pour récupérer la "ligne suivante" (j'imagine avec la colonne Ordre), puis utiliser un CASE pour sélectionner les valeurs à renvoyer.
    Accessoirement tu devrais utiliser JOIN pour les jointures, la requête serait plus lisible:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT B.IDb, B.ordre, A.titre
    FROM A
    inner join B on B.IDa = A.IDa 
    inner join C on B.IDb = C.IDb

    Je note d'ailleurs une bizarrerie dans la description des tables: si IdB est bien la clé primaire de Table B, un IdB n'est lié qu'à un IdA. Donc la colonne IdA dans la table C est inutile...

    Tatayo.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2019
    Messages : 4
    Par défaut
    Merci Tatayo. D'ores et déjà pour répondre à ta dernière remarque (la colonne IdA dans la table C est inutile) : c'est dans la table C que l'on sait, pour un enregistrement de A, quel est l'enregistrement B à renvoyer (dans la requête actuelle).

  4. #4
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 363
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 363
    Par défaut
    Tu as l'IdB dans la table C, donc si IdB est la clé primaire de la table B, il est inutile de passer par la table A...
    Visiblement pour une ligne de C tu n'as qu'une ligne de B (via IdB dans la table C), et pour une ligne de B tu n'as qu'une ligne de A (via IdA).
    Donc tu peux faire une jointure entre C et B via IdB, et entre B et A via IdA. C'est d'ailleurs ce que tu fais dans ta requête, tu n'utilises pas C.IdA…

    Tatayo.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2019
    Messages : 4
    Par défaut
    Sans doute ai-je fait une erreur, mais dans l'idée, la table C permet (ou devrait permettre) de désigner, pour chaque un enregistrement A, lequel de ses enregistrements B est à retourner (ici le numéro 18).
    Si l'on modifie l'enregistrement de C par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IDc, IDb, IDa
    27, 19, 7
    on doit obtenir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IDb, ordre, titre
    19, 3, toto

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Peut être quelque chose comme ç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
    28
    29
    30
    31
    32
      with data as (
    select b.idb, b.ordre, a.titre, b.deb, b.fin, c.idc
         , lead(b.idb) over (partition by a.ida order by b.ordre) as next_idb
         , lead(b.ordre) over (partition by a.ida order by b.ordre) as next_ordre
         , lead(b.deb) over (partition by a.ida order by b.ordre) as next_deb              
             -- Si la ligne existe dans C (donc C non NULL)
             -- Et fin est vrai
             -- Et le deb suivant est faux
             -- Alors on sélectionne la ligne suivante de B
             -- Sinon NULL
         , case when c.idb is not null 
                 and b.fin = 'vrai'
                 and lead(b.deb) over (partition by a.ida order by b.ordre) = 'faux' 
                then lead(b.idb) over (partition by a.ida order by b.ordre)
            end as next_idb_deb_fin
         , case when c.idb is not null
                 and b.fin = 'vrai' 
                 and lead(b.deb) over (partition by a.ida order by b.ordre) = 'faux'
                then lead(b.ordre) over (partition by a.ida order by b.ordre)            
            end as next_ordre_deb_din
      from table_a a
      join table_b b on b.ida = a.ida
        -- jointure externe pour permettre de lire la ligne suivante dans table_b (lead)
      left join table_c c on c.idb = b.idb
    )
        -- COALESCE : si on a trouvé une ligne suivante candidate, sinon on prend la valeur existante dans C
    select coalesce(next_idb_deb_fin, idb)
         , coalesce(next_ordre_deb_din, ordre)
         , titre
      from data d
        -- on refiltre les NULL de C générés par la jointure externe
     where idc is not null;

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 24/05/2014, 12h38
  2. Réponses: 7
    Dernier message: 08/08/2011, 11h42
  3. [AC-2007] Requête de sélection sur deux tables
    Par Petit Rasta dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 27/05/2010, 17h08
  4. [AC-2007] Requête sélection sur deux tables liées
    Par rogerfon dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 10/04/2010, 14h30
  5. Sélection sur deux critères
    Par Hbenne dans le forum Access
    Réponses: 2
    Dernier message: 07/04/2006, 16h18

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