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

SQL Oracle Discussion :

Un select différent dans chaque colonne


Sujet :

SQL Oracle

  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut Un select différent dans chaque colonne
    Bonjour,

    Pour simplifier, j'ai une table partner ( code, status).
    Dans ma première colonne, j'aimerais avoir le nombre total de partner ayant comme status 'OK', et dans la 2ème colonne, le nombre total de partner ayant comme status 'No'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select count(p.status ='Ok'), count(p.status ='No')
    from partners p
    Je sais que ça c'est impossible, j'ai essayé aussi avec les sous requetes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    select p1.ok,p2.n
    from
        (select count(*) as o
        from partners p
        where p.status='ok')p1,
        (select count(*)as n
        from partners p
        where p.status='no')p2
    Je ne vois pas comment je peux faire!!!
    merci beaucoup de votre aide
    claire

  2. #2
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut,

    Essaie ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT COUNT (CASE
                     WHEN p.status = 'Ok'
                        THEN 1
                     END) CPT_OK, COUNT (CASE
                                  WHEN p.status = 'No'
                                     THEN 1
                               END)CPT_KO
      FROM partners p
    Demo
    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
     
    SQL> WITH p AS
      2       (SELECT 1 code, 'Ok' status
      3          FROM DUAL
      4        UNION ALL
      5        SELECT 2 code, 'Ok' status
      6          FROM DUAL
      7        UNION ALL
      8        SELECT 3 code, 'No' status
      9          FROM DUAL)
     10  SELECT COUNT (CASE
     11                   WHEN p.status = 'Ok'
     12                      THEN 1
     13                END) cpt_ok, COUNT (CASE
     14                                       WHEN p.status = 'No'
     15                                          THEN 1
     16                                    END) cpt_ko
     17    FROM p;
     
        CPT_OK     CPT_KO
    ---------- ----------
             2          1
     
    SQL>

  3. #3
    Membre Expert Avatar de fatsora
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 103
    Par défaut
    ou

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT SUM(OK_count) OK,
           SUM(NO_count) NO
    FROM
           (SELECT  DECODE(status,'OK',COUNT(*),0) OK_COUNT,
                    DECODE(status,'NO',COUNT(*),0) NO_COUNT
           FROM     partner
           GROUP BY status
           );

  4. #4
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Citation Envoyé par fatsora Voir le message
    ou

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT SUM(OK_count) OK,
           SUM(NO_count) NO
    FROM
           (SELECT  DECODE(status,'OK',COUNT(*),0) OK_COUNT,
                    DECODE(status,'NO',COUNT(*),0) NO_COUNT
           FROM     partner
           GROUP BY status
           );
    A mon avis tu n'as pas besoin de la sous-requête ni le groupe by

  5. #5
    Membre Expert Avatar de fatsora
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 103
    Par défaut
    si

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select sum('OK') OK,sum('NO') NO
    from partner
    group by status
    /

    invalid number

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select sum(OK_count) OK,sum(NO_count) NO from (select decode(status,'OK',count(*),0) OK_COUNT,
     decode(status,'NO',count(*),0) NO_COUNT
    from partner
    )
    /

    renvoie not a single group function !!

    donc on a besoin sous requete et group by
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select * from partner;

    CODE,STATUS
    11111,OK,
    11112,OK,
    11113,OK,
    11113,NO,
    112,NO,
    113,NO,
    114,NO,
    115,NO,
    116,NO,
    11114,OK,
    11115,OK,
    11116,OK,
    11117,OK,
    11118,OK,
    11119,OK,

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT SUM(OK_count) OK,
           SUM(NO_count) NO
    FROM
           (SELECT  DECODE(status,'OK',COUNT(*),0) OK_COUNT,
                    DECODE(status,'NO',COUNT(*),0) NO_COUNT
           FROM     partner
           GROUP BY status
           );

    OK,NO
    9,6,

  6. #6
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    SQL> set autotrace on exp
    SQL> WITH p AS
      2       (SELECT 1 code, 'Ok' status
      3          FROM DUAL
      4        UNION ALL
      5        SELECT 2 code, 'Ok' status
      6          FROM DUAL
      7        UNION ALL
      8        SELECT 3 code, 'No' status
      9          FROM DUAL)
     10  SELECT SUM(OK_count) OK,
     11         SUM(NO_count) NO
     12  FROM
     13         (SELECT  DECODE(STATUS,'Ok',COUNT(*),0) OK_COUNT,
     14                  DECODE(STATUS,'No',COUNT(*),0) NO_COUNT
     15         FROM     p
     16         GROUP BY STATUS
     17         );
     
            OK         NO
    ---------- ----------
             2          1
     
     
    Plan d'exécution
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=1 Bytes=26)
       1    0   SORT (AGGREGATE)
       2    1     VIEW (Cost=7 Card=3 Bytes=78)
       3    2       HASH (GROUP BY) (Cost=7 Card=3 Bytes=12)
       4    3         VIEW (Cost=6 Card=3 Bytes=12)
       5    4           UNION-ALL
       6    5             FAST DUAL (Cost=2 Card=1)
       7    5             FAST DUAL (Cost=2 Card=1)
       8    5             FAST DUAL (Cost=2 Card=1)
     
     
     
    SQL> /* Formatted on 2008/12/03 11:02 (Formatter Plus v4.8.8) */
    SQL> WITH p AS
      2       (SELECT 1 code, 'Ok' status
      3          FROM DUAL
      4        UNION ALL
      5        SELECT 2 code, 'Ok' status
      6          FROM DUAL
      7        UNION ALL
      8        SELECT 3 code, 'No' status
      9          FROM DUAL)
     10  SELECT COUNT (CASE
     11                   WHEN p.status = 'Ok'
     12                      THEN 1
     13                END) cpt_ok, COUNT (CASE
     14                                       WHEN p.status = 'No'
     15                                          THEN 1
     16                                    END) cpt_ko
     17    FROM p;
     
        CPT_OK     CPT_KO
    ---------- ----------
             2          1
     
     
    Plan d'exécution
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=1 Bytes=4)
       1    0   SORT (AGGREGATE)
       2    1     VIEW (Cost=6 Card=3 Bytes=12)
       3    2       UNION-ALL
       4    3         FAST DUAL (Cost=2 Card=1)
       5    3         FAST DUAL (Cost=2 Card=1)
       6    3         FAST DUAL (Cost=2 Card=1)
     
     
     
    SQL>

  7. #7
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par salim11 Voir le message
    A mon avis tu n'as pas besoin de la sous-requête ni le groupe by
    Salim a raison. Il faut juste mettre le decode à l'intérieur du count. Cela donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select count(decode(STATUS,'OK',1) OK, count(decode(STATUS,'NO',1) NO
    from partners;

  8. #8
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut
    merci beaucoup pur toutes vos réponses, je vais regarder.
    Je pensais bien que ce ne serait pas facile mais ça dépasse toutes mes attentes

    je reviens vers vous dès que j'ai décodé votre code
    merci encore
    claire

  9. #9
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut !

    En fait, la seule chose compliquée ici, c'est la lutte pour savoir comment réécrire sous une forme strictement équivalente la première requête que t'a donné Salim...
    (parce que finalement, on a juste remplacé CASE par decode...)

    Donc,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CASE Status WHEN 'Ok' THEN 1 ELSE 0 END
    te renvoie pour chaque ligne 1 si c'est OK, 0 sinon.
    Si tu fais la somme de ces valeurs, tu as le nombre de Ok.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sum(CASE Status WHEN 'Ok' THEN 1 ELSE 0 END)
    De la même manière, tu comptes les 'No'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sum(CASE Status WHEN 'No' THEN 1 ELSE 0 END)
    Voilà voilà...

  10. #10
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut
    merci beaucoup
    Ca marche bien sur une table, même sur deux mais lorsque je complique un peu la requête, pas d'erreur mais prend énormément de temps (j'ai dû arrêter pendant l'exécution)

    voici mon code:

    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
     
    select 
    count(t.partner_code) "nb approved",
    count(t2.partner_code) "nb refusé"
    from
     
        (select p.partner_code
        from partners p,partner_profile pp
        where p.partner_code=pp.partner_code
        and p.delete_flag='N'
        and pp.partner_status is null
        and pp.date_stamp between '01/11/08' and '30/11/08') t,
     
        (select p.partner_code
        from partners p,partner_profile pp
        where p.partner_code=pp.partner_code
        and p.delete_flag='Y'
        and pp.partner_status ='TEMPORARY'
        and pp.date_stamp between '01/11/08' and '30/11/08') t2
    en fait, j'aimerais dans une colonne avoir mes partner validé et dans une autre mes partner refusés (et cela pour une date précise). Pour cela il me faut le champs delete_flag de la table Partners et le champ partner_status de la table partner_profile.
    Est-ce que quelqu'un voit mon erreur?

    Dans tous les cas, merci beaucoup pour vos réponses

    claire

  11. #11
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut


    Il faut que je vérifie les résultats mais àa a l'air de marcher:

    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
     
    select t.a,t2.r 
    from
        (select count(p.partner_code) as a
        from partners p,partner_profile pp
        where p.partner_code=pp.partner_code
        and p.delete_flag='N'
        and pp.partner_status is null
        and pp.date_stamp between '01/11/08' and '30/11/08') t,
     
        (select count(p.partner_code) as r
        from partners p,partner_profile pp
        where p.partner_code=pp.partner_code
        and p.delete_flag='Y'
        and pp.partner_status ='TEMPORARY'
        and pp.date_stamp between '01/11/08' and '30/11/08') t2
    merci encore, vous êtes comme toujours super

    claire

  12. #12
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Au niveau perf, je ne suis pas sûr que ce soit le top , mais essaie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT count(CASE WHEN p.delete_flag='N' AND pp.partner_status IS NULL THEN 1 END) AS a,
       count(CASE WHEN p.delete_flag='Y' AND pp.partner_status = 'TEMPORARY' THEN 1 END) 
    FROM partners p,partner_profile pp
    WHERE p.partner_code=pp.partner_code
    AND pp.date_stamp BETWEEN '01/11/08' AND '30/11/08';
    Compare le plan d'exécution de ta requête et de celle que je propose.

  13. #13
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut
    tu as raison au niveau perf c'est bidon, je vais essayer ta méthode

    merci

  14. #14
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut
    C'est vrai que ça va beaucoup plus vite mais depuis tout à l'heure j'ai rajouté 1 nouvelle contraintes, il me faut le nb de code par pays

    mes tables sont:
    - partners: partner_code...
    - partners_addresses: partner_code, address_code...
    - addresses: address_coded, country...

    J'ai essayé de cette manière mais 2 pb:
    - très long
    - en plus, j'aimerais que tous mes pays soient affichés et qu'il y ait 0 quand pas de partner mais ne marche pas


    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
    33
    34
    35
    36
    37
    38
     
    select distinct(a.country),t.a,t2.r as dummys,t3.r as duplicate,t4.r as denied
    --count(t.partner_code) "nb approved",
    --count(t2.partner_code) "nb refusé"
    from
    ---------------------------------------------------------------------------------------------------------------------
    --
    --PARTNER APPROVED
    --
    ----------------------------------------------------------------------------------------------------------------------   
        (select count(p.partner_code) as a,ad.country
        from partners p,partner_profile pp, partners_addresses pa,addresses ad
        where p.partner_code=pp.partner_code
        and p.partner_code=pa.partner_code
        and pa.addr_code=ad.addr_code
         and p.delete_flag='N'
        and pp.partner_status is null
        and p.creation_date between '01/10/08' and '31/10/08'
        group by ad.country
        order by ad.country) t,
    ---------------------------------------------------------------------------------------------------------------------
    --
    --PARTNER DENIED pour cause de MAUVAISE INFO
    --
    ----------------------------------------------------------------------------------------------------------------------       
        (select count(p.partner_code) as r,ad.country
        from partners p,partner_profile pp, partners_addresses pa,addresses ad
        where p.partner_code=pp.partner_code
        and p.partner_code=pa.partner_code
        and pa.addr_code=ad.addr_code
        and p.delete_flag='Y'
        and pp.partner_status ='TEMPORARY'
        and p.creation_date between '01/10/08' and '31/10/08'
        group by ad.country
        order by ad.country) t2,
        addresses a
    where a.country =t.country
    and a.country =t2.country
    j'ai essayé avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    where a.country (+)=t.country
    and a.country (+)=t2.country
    mais pas possible car ne peut faire que une seule jointure de ce type

    J'ai commencé aussi à regarder les fonctions analytiques mais je ne crois pas que ça va me servir ici.

    Je vais continuer à partir de votre solution

    merci

  15. #15
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Par défaut
    Vous êtes géniaux

    voilà le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT a.country,
           count(CASE WHEN p.delete_flag='N' AND pp.partner_status IS NULL THEN 1 END) AS a,
           count(CASE WHEN p.delete_flag='Y' AND pp.partner_status = 'TEMPORARY' THEN 1 END) AS D 
    FROM partners p,partner_profile pp,partners_addresses pa, addresses a
    WHERE p.partner_code=pp.partner_code
    and p.partner_code=pa.partner_code
    and pa.addr_code=a.addr_code
    AND pp.date_stamp BETWEEN '01/11/08' AND '30/11/08'
    group by a.country;
    et ça marche vite en plus

    merci encore pour tout, je vais finaliser cette requête (car évidemment il me reste encore quelques critères à prendre en compte).

    a tout à l'heure ou bon week-end

    claire

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

Discussions similaires

  1. [AC-2003] imputer des taux différents dans chaque colonne d'un même formulaire
    Par Ardiden31 dans le forum VBA Access
    Réponses: 16
    Dernier message: 16/04/2012, 14h28
  2. Réponses: 2
    Dernier message: 24/05/2011, 09h32
  3. Concatener données de tables différentes dans même colonne
    Par ARONE dans le forum Développement
    Réponses: 3
    Dernier message: 26/02/2009, 15h36
  4. objets différents dans une colonne de datagrid
    Par Pascale38 dans le forum Flex
    Réponses: 25
    Dernier message: 22/01/2009, 18h05
  5. Nombre de valeurs différentes dans une colonne
    Par KrusK dans le forum Langage SQL
    Réponses: 4
    Dernier message: 24/08/2005, 14h18

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