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

Requêtes PostgreSQL Discussion :

2 SELECT cote a cote


Sujet :

Requêtes PostgreSQL

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mai 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut 2 SELECT cote a cote
    Bonjour à tous,
    je cherche a obtenir côte a côte le résultat de 2 requêtes distinctes, sans jointure !

    Pour info, j'utilise PostegreSQL.

    Voici les deux requêtes SQL :

    SELECT fp_folio, mo_monto
    FROM pro_folio_programa
    INNER JOIN pro_movimiento ON mo_programa = fp_programa AND mo_subprograma = fp_subprograma AND mo_ano = fp_ano AND mo_folio = fp_folio AND mo_anofolio = fp_anofolio
    WHERE fp_programa = 5 AND fp_subprograma = 'A' AND fp_ano = 2008 AND fp_anofolio = 2009 AND mo_cuenta = 3
    AND mo_imputa = 'D'
    ORDER BY fp_folio, mo_cuenta;
    Et la suivante, qui diffère uniquement sur la dernière condition du WHERE :

    SELECT fp_folio, mo_monto
    FROM pro_folio_programa
    INNER JOIN pro_movimiento ON mo_programa = fp_programa AND mo_subprograma = fp_subprograma AND mo_ano = fp_ano AND mo_folio = fp_folio AND mo_anofolio = fp_anofolio
    WHERE fp_programa = 5 AND fp_subprograma = 'A' AND fp_ano = 2008 AND fp_anofolio = 2009 AND mo_cuenta = 3
    AND mo_imputa = 'H'
    ORDER BY fp_folio, mo_cuenta;
    J'obtiens séparément deux tables résultat sous la forme :
    fp_folio | mo_monto
    1 | 100

    fp_folio | mo_monto
    2 | 200
    3 | 300
    Il s'agit en fait des mouvements bancaires d'un compte, la 1ere table donnant les mouvements entrants, la 2eme les mouvements sortants.

    Mon but est d'obtenir une seule table de la forme :
    fp_folio | mo_monto | fp_folio | fp_monto
    2 | 200 | 1 | 100
    3 | 300 | 0 | 0
    Une des difficulté majeure se trouve dans le fait que les deux requêtes ne donnent pas le même nombre de ligne. Évidement puisqu'il n'y pas de raison que vous ayez dépensé de l'argent autant de FOIS que vous en avez reçu.

    L'autre est de "coller" le résultat de la seconde requête à droite de la première sans avoir a les joindre, et de remplir les dernières lignes vide d'une des deux requêtes (celle qui a la moins de ligne) par des 0.

    On m'a suggéré de chercher du côté des CURSOR mais j'ai beau avoir fait suer Google et mangé des tutoriels sur le sujet, je ne suis arrivé à rien.

    Voila, si quelqu'un peut me guider, d'avance merci,

    Cyrille

  2. #2
    Membre averti
    Homme Profil pro
    Informaticien
    Inscrit en
    Juin 2004
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gers (Midi Pyrénées)

    Informations professionnelles :
    Activité : Informaticien
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2004
    Messages : 182
    Points : 357
    Points
    357
    Par défaut
    Bonjour

    il est peut-être possible d'utiliser UNION

    la seule contrainte étant que les deux requêtes doivent renvoyer les mêmes colonnes.

    il faut donc renommer les colonnes et créer leurs inverses dans les requêtes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT col1,col2,'' as col3,'' as col4
    UNION
    SELECT  '' as col1,'' as col2,col3,col4
    (attention, je ne suis pas sur de la bonne syntaxe du as...)

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    C'est possible avec un full join entre les 2 requêtes et un critère de jointure qui soit le numéro de ligne.
    En plus détaillé:
    - dans la 2eme requête renommer les 2 colonnes sorties car il faut qu'elles aient un nom différent pour le résultat final à 4 colonnes. Mettons qu'on ajoute un "2" à la fin
    - créer 2 séquences temporaires seq1 et seq2
    - ajouter nextval('seq1') as c1 aux résultats de la 1ere requête et nextval('seq2') as c2 à la 2eme
    - Combiner tout ça dans un fulll join
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT fp_folio, mo_monto, fp_folio2, mo_monto2 FROM
       (SELECT fp_folio, mo_monto, nextval('seq1') as c1 FROM .... )
     FULL JOIN
      (SELECT fp_folio as fp_folio2, mo_monto as mo_monto2,  nextval('seq2') as c2 FROM ...)
     ON (c1=c2)
    Les valeurs "manquantes" seront des NULL et non pas des zéros
    Ceci dit c'est changeable facilement en appliquant la fonction coalesce() à toutes les colonnes du SELECT principal, du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT coalesce(fp_folio, 0), coalesce(...
    Pour que ça marche il faut impérativement que les séquences commençent à 1 au début de la requête (hélas postgresql n'a pas le rownum d'oracle sinon on pourrait se passer des séquences).
    Il faut donc créer des séquences temporaires à chaque fois ou bien utiliser setval() pour les remettre à 1 avant chaque exécution.

  4. #4
    Candidat au Club
    Inscrit en
    Mai 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mai 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Merci
    Merci d'avoir répondu aussi rapidement.

    Vos deux propositions me paraissent très bien, je ne peux malheureusement pas les tester ce week-end car je n'ai acces à la base de données qu'au boulot.

    Je vais donc les tester ce lundi et je vous ferais un compte rendu au plus vite.

    Merci encore.

    Cyrille

  5. #5
    Candidat au Club
    Inscrit en
    Mai 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mai 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Résolution
    J'ai testé vos deux solutions, et voila le topo :

    La solution d'utiliser la UNION ne convient pas car, même en créant l'inverse des colonnes dans chacune des 2 requêtes, les données ne se positionnent pas côte à côte mais bien l'une en dessous de l'autre, comme je l'avais remarqué auparavant. Le résultat obtenu est :
    fp_folio | mo_monto | fp_folio | fp_monto
    2 | 200 | 0 | 0
    3 | 300 | 0 | 0
    0 | 0 | 1 | 100
    La deuxième solution, qui utilise un FULL JOIN, m'apporte exactement le résultat attendu. Juste un petit détails, il est nécessaire de donner un nom à chaque sous-requête pour que cela fonctionne :

    SELECT fp_folio, mo_monto, fp_folio2, mo_monto2 FROM
    (SELECT fp_folio, mo_monto, NEXTVAL('seq1') AS c1 FROM .... ) AS req1
    FULL JOIN
    (SELECT fp_folio AS fp_folio2, mo_monto AS mo_monto2, NEXTVAL('seq2') AS c2 FROM ...) AS req2
    ON (c1=c2)
    Merci encore pour vos réponses, vous m'avez enlever une sale épine du pied.

    Cyrille

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/07/2007, 23h44
  2. 2 div cote a cote encadrés, impossible?
    Par ned-flanders dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 27/03/2007, 15h25
  3. Cote double cote
    Par mpat dans le forum ASP
    Réponses: 9
    Dernier message: 06/09/2005, 10h29
  4. ranger trois tableaux cote a cote
    Par Art19 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 28/07/2005, 11h58
  5. [HTML] Tableaux cote a cote
    Par sg-40 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 08/06/2005, 13h30

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