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 :

[Oracle 10g] Retrancher 2 lignes en SQL


Sujet :

Langage SQL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 560
    Points : 148
    Points
    148
    Par défaut [Oracle 10g] Retrancher 2 lignes en SQL
    Bonjour,

    Je souhaite retrancher 2 lignes en SQL.

    En gros j'ai 2 requêtes qu me ramnènent comme vous le voyez une somme.
    Je souhaiterais donc retrancher ces deux sommes.
    Comment faire le retranchement ?

    Première requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT CL.C_CLIENT, C.C_NUM_COMPTE, SUM(N_MONTANT_ANN) AS S1 
    FROM MVT_COMPTABLE M
      INNER JOIN COMPTE C ON M.C_NUMERO_COMPTE = C.C_NUMERO_COMPTE
      INNER JOIN CLIENT CL ON CL.C_ID_CLIENT = M.C_ID_CLIENT
    WHERE D_ANNEE_REF='2008' 
    GROUP BY CL.C_CLIENT, C.C_NUM_COMPTE ORDER BY CL.C_CLIENT ASC
    Deuxième requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT CL.C_CLIENT, C.C_NUM_COMPTE, SUM(N_MONTANT_ANN) AS S2 
    FROM MVT_COMPTABLE M
      INNER JOIN COMPTE C ON M.C_NUMERO_COMPTE = C.C_NUMERO_COMPTE
      INNER JOIN CLIENT CL ON CL.C_ID_CLIENT = M.C_ID_CLIENT
    WHERE D_ANNEE_REF='2007' 
    GROUP BY CL.C_CLIENT, C.C_NUM_COMPTE ORDER BY CL.C_CLIENT ASC
    Ceci en évitant de passer par des tables temporaires.

    Merci d'avance pour toute information complémentaire.

  2. #2
    Membre confirmé Avatar de elbj
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Services à domicile

    Informations forums :
    Inscription : Novembre 2004
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Bonjour

    Dans un premier temps tu transformes tes requêtes en une vue générique :
    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
     
    CREATE VIEW V_MONTANTS_ANNUELS AS
    SELECT
      D_ANNEE_REF,
      CL.C_ID_CLIENT
      CL.C_CLIENT,
      C.C_NUM_COMPTE,
      SUM(N_MONTANT_ANN) AS MONTANT_ANNUEL
    FROM MVT_COMPTABLE M
      INNER JOIN COMPTE C ON M.C_NUMERO_COMPTE = C.C_NUMERO_COMPTE
      INNER JOIN CLIENT CL ON CL.C_ID_CLIENT = M.C_ID_CLIENT
    GROUP BY 
      D_ANNEE_REF, 
      CL.C_ID_CLIENT
      CL.C_CLIENT, 
      C.C_NUM_COMPTE 
    ORDER BY 
      D_ANNEE_REF, 
      CL.C_CLIENT ASC
    Ensuite il te restera à écrire tout simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT
      A1.C_CLIENT,
      A1.C_NUM_COMPTE,
      A1.D_ANNEE_REF AS ANNEE_UN,
      COALESCE(A1.MONTANT_ANNUEL,0) AS MONTANT_UN,
      A2.D_ANNEE_REF AS ANNEE_DEUX,
      COALESCE(A2.MONTANT_ANNUEL,0) AS MONTANT_DEUX,
      (COALESCE(A1.MONTANT_ANNUEL,0) - COALESCE(A2.MONTANT_ANNUEL,0)) AS DIFFERENCE
    FROM V_MONTANTS_ANNUELS A1
      LEFT JOIN V_MONTANTS_ANNUELS A2 
        ON A2.C_ID_CLIENT = A1.C_ID_CLIENT 
        AND A2.D_ANNEE_REF = '2007'
    WHERE A1.D_ANNEE_REF = '2008'
    ORDER BY A1.C_CLIENT ASC
    Ca devrait te permettre de résoudre ton problème.

  3. #3
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 737
    Points
    11 737
    Par défaut
    Variante sans vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT CL.C_CLIENT, C.C_NUM_COMPTE, 
      SUM(
        CASE D_ANNEE_REF 
          WHEN '2008' THEN N_MONTANT_ANN
          WHEN '2007' THEN - N_MONTANT_ANN
        END
        ) AS S1 
    FROM MVT_COMPTABLE M
      INNER JOIN COMPTE C ON M.C_NUMERO_COMPTE = C.C_NUMERO_COMPTE
      INNER JOIN CLIENT CL ON CL.C_ID_CLIENT = M.C_ID_CLIENT
    WHERE D_ANNEE_REF IN ('2007', '2008')
    GROUP BY CL.C_CLIENT, C.C_NUM_COMPTE ORDER BY CL.C_CLIENT ASC

    Quel est ton SGBD ?

    Quel est le type de la colonne D_ANNEE_REF ?

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 560
    Points : 148
    Points
    148
    Par défaut
    Merci Antoun pour ta deuxième proposition mais en fait mes deux requêtes ne sont pas forcément les mêmes.

    Cela veut-il dire qu'il faut créer 2 vues différentes ?

    Merci pour toute information complémentaire.

  5. #5
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 737
    Points
    11 737
    Par défaut
    Normalement, tu peux faire un truc 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
    SELECT ..., SUM(S1) AS S1
    FROM (
      SELECT ..., SUM(N_MONTANT_ANN) AS S1
      FROM ...
      WHERE D_ANNEE_REF = '2008'
      GROUP BY...
      UNION ALL
      SELECT ..., N_MONTANT_ANN
      FROM ...
      WHERE D_ANNEE_REF = '2007'
      GROUP BY...
    )
    GROUP BY...

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 560
    Points : 148
    Points
    148
    Par défaut
    OK merci pour vos réponses mais en fait comme je le disais les requêtes ne sont pas identiques.

    Voilà les 2 sommes pour lesquelles il faut que fasse une différence.

    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
     
    -- PREMIERE REQUETE
    select (L_MOIS/12)*(SUM(N_MONTANT)) AS S1, C_ID_CLIENT, C_ID_PRESTATION, C_NUM_COMPTE
    FROM CHIFFRE_AFFAIRE 
    group by C_ID_CLIENT, C_ID_PRESTATION, C_NUM_COMPTE, L_MOIS
    ORDER BY C_ID_PRESTATION ASC
     
    -- DEUXIEME REQUETE
    SELECT SUM(N_MONTANT_ANN) AS S2, CL.C_ID_CLIENT, C.C_ID_PRESTATION, C.C_NUM_COMPTE 
    FROM MVT_COMPTABLE M
    INNER JOIN COMPTE C ON M.C_NUMERO_COMPTE = C.C_NUMERO_COMPTE
    INNER JOIN CLIENT CL ON CL.C_ID_CLIENT = M.C_ID_CLIENT
    WHERE D_ANNEE_REF='2008' 
    GROUP BY CL.C_ID_CLIENT, C.C_ID_PRESTATION, C.C_NUM_COMPTE 
    ORDER BY C.C_ID_PRESTATION ASC
    Le problème c'est que ces deux requêtes ne me donnent pas forcément le même nombre de lignes. De, plus il faut "matcher" à chaque fois sur le client, la prestation et le compte.

    Merci de me dire si c'est jouable !

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 560
    Points : 148
    Points
    148
    Par défaut
    Merci à elbj, j'ai créé 2 vues en reprenant son exemple et cela fonctionne très bien.
    A+

  8. #8
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 737
    Points
    11 737
    Par défaut
    l'intérêt de l'union est précisément de te permettre d'avoir deux requêtes différentes. La seule contrainte est qu'il y ait les mêmes colonnes (ou du moins des types compatibles).

    Pour "matcher" les deux requêtes, la seule solution simple est de dupliquer les conditions.

    Tu ne nous a pas dit quel est ton SGBD ?

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 560
    Points : 148
    Points
    148
    Par défaut
    Je travaille sous ORACLE 10g.

  10. #10
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 737
    Points
    11 737
    Par défaut
    Désolé, je n'avais pas vu ton code et interprété de travers l'histoire du "match" ...

    Juste pour l'anecdote, la solution avec UNION :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT SUM(S1) AS S1, C_ID_CLIENT, C_ID_PRESTATION, C_NUM_COMPTE
    FROM (
      SELECT L_MOIS/12 * SUM(N_MONTANT) AS S1, C_ID_CLIENT, C_ID_PRESTATION, C_NUM_COMPTE
      FROM CHIFFRE_AFFAIRE  
      UNION ALL
      SELECT - N_MONTANT_ANN, CL.C_ID_CLIENT, C.C_ID_PRESTATION, C.C_NUM_COMPTE 
      FROM MVT_COMPTABLE M
        INNER JOIN COMPTE C ON M.C_NUMERO_COMPTE = C.C_NUMERO_COMPTE
        INNER JOIN CLIENT CL ON CL.C_ID_CLIENT = M.C_ID_CLIENT
      WHERE D_ANNEE_REF='2008' 
      ) tmp
    GROUP BY CL.C_ID_CLIENT, C.C_ID_PRESTATION, C.C_NUM_COMPTE 
    ORDER BY C.C_ID_PRESTATION ASC

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

Discussions similaires

  1. Oracle 10g - OEM vs Ligne de commande
    Par korian dans le forum Administration
    Réponses: 0
    Dernier message: 20/06/2011, 14h04
  2. [Oracle 10g] Paralléliser du code PL/SQL
    Par Yoh dans le forum Oracle
    Réponses: 3
    Dernier message: 06/05/2011, 12h07
  3. [Oracle 10G] SQLPLUS en ligne de commande
    Par shaun_the_sheep dans le forum Sql*Plus
    Réponses: 5
    Dernier message: 15/12/2008, 16h03
  4. [Oracle 10g]probleme avec une requette sql
    Par ragasy29 dans le forum SQL
    Réponses: 6
    Dernier message: 02/05/2007, 13h45
  5. [ORACLE 10g] Droits en ligne sur une table
    Par Cerberes dans le forum Oracle
    Réponses: 4
    Dernier message: 04/02/2005, 10h39

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