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 :

Inverser le sens d'une requête SQL..


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 134
    Par défaut Inverser le sens d'une requête SQL..
    Bonjour

    Je possède une table T1 comme ceci :
    Nombre(Number(5))
    Chaîne(Varchar2(40))

    Le champ 'nombre' contient des valeurs numériques, de 0 à 86000 environ (il y en a environ 35000 différents en tout).

    J'ai actuellement une requête croisée, me retournant le total des champs possédant un nombre et une chaîne donnée, soit environ ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Chaîne    0    1  ...  20    30 ....  90000   100000  ...
     
    chaîne1  12    43    546     76      7878       785
    chaîne2   2    345   757     67       876        67
    chaîne3  437   3     43      76       879        908
    J'ai donc un regroupement par chaîne, et quelques enregistrements du champ "Nombre". En effet, je n'ai pas 1 colonne par valeur, mais un regroupement! Je m'explique :
    je compte de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT chaîne,
    count(CASE WHEN Nombre=0 THEN 1 END)AS M_0,
    count(CASE WHEN Nombre=1 THEN 1 END)AS M_1,
    ...
    count(CASE WHEN Nombre>=100 AND Nombre<200 THEN 1 END)AS M_100_200,
    ...
    count(CASE WHEN Nombre>=90000 AND Nombre<100000 THEN 1 END)AS M_90000_100000,
    ...
    FROM T1
    GROUP BY chaîne ORDER BY chaîne;
    Le soucis c'est que je souhaite obtenir l'inverse! Soit les chaînes en entête de colonne, et les valeurs de "Nombre" (regroupés comme je vous l'ai montré) en entête de ligne...
    Pour les chaînes en entête ce n'est pas un problème, j'ai le moyen de les récupérer toutes (donc je peux faire un "CASE(WHEN chaine="chaine1" THEN 1 END)" etc..), mais comment faire pour le regroupement du champ "nombre" ? (si je met "GROUP BY nombre", j'ai bien évidemment les 35000 lignes qui s'affichent...)!

    Une idée ?...

    Merci beaucoup

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Il suffit de regrouper tous vos cases sur les nombres en un seul, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CASE
      WHEN Nombre = 0 THEN 0
      WHEN Nombre = 1 THEN 1
      ...
      WHEN Nombre BETWEEN 100 AND 200 THEN 100
      ...
      WHEN Nombre BETWEEN 90000 AND 100000 THEN 90000
      ...
    END
    Si vous avez une logique de regroupement, ce serait encore mieux il suffirait d'appliquer la fonction mathématique.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 134
    Par défaut
    c'était donc ça ? Je n'ai pas encore testé (j'ai surtout essayé de comprendre ^^)! D'ailleurs, si je comprend bien ça signifie qu'il n'y a plus de clause GROUP BY !? (de toute façon théoriquement ça doit planter si j'en met une), étant donné que tout est déjà regroupé dans un seul champ!
    C'est génial, je vais tester ça de suite

    ps : j'ai un algorithme qui me fait la petite règle de regroupement des nombres Effectivement ça serait beaucoup trop long sinon
    Merci encore !!

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Le regroupement doit être et dans le select et dans le group by, bien entendu.
    Regardez je vous ai fait les deux pivots rapidement ici :
    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
    With MaTable as
    (
    select 'A' as c1, 12 as c2 from dual union all
    select 'B'      , 23       from dual union all
    select 'A'      ,  9       from dual union all
    select 'B'      , 31       from dual
    )
      select c1,
             count(case when c2 between  0 and  9 then 1 end) as c2_10,
             count(case when c2 between 10 and 19 then 1 end) as c2_20,
             count(case when c2 between 20 and 29 then 1 end) as c2_30
        from MaTable
    group by c1
    order by c1 asc;
     
    C1	C2_10	C2_20	C2_30
    A	1	1	0
    B	0	0	1
    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
    With MaTable as
    (
    select 'A' as c1, 12 as c2 from dual union all
    select 'B'      , 23       from dual union all
    select 'A'      ,  9       from dual union all
    select 'B'      , 31       from dual
    )
      select floor(c2/10) as c2_grp,
             count(case c1 when 'A' then 1 end) as c1_A,
             count(case c1 when 'B' then 1 end) as c1_B
        from MaTable
    group by floor(c2/10)
    order by floor(c2/10) asc;
     
     
    C2_GRP	C1_A	C1_B
    0	1	0
    1	1	0
    2	0	1
    3	0	1

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    134
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 134
    Par défaut
    Merci beaucoup, mais il y a une chose que je ne comprend pas...
    Tout à l'heure vous faisiez un CASE global contenant tous les when, et maintenant vous faites un floor(c2/10)

    Parce que j'avais fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select CASE WHEN nombre=0 THEN 0 WHEN nombre=1 THEN 1 etc..,
    count(case chaine when 'chaine1' then 1 end) AS c1_A,
    count(case chaine when 'chaine2' then 1 end) AS c1_B
    FROM T1
    Mais à vrai dire je me retrouve avec une erreur "ora-00939", soit "too many arguments"... Donc il faut que je limite les champs dans MA requête

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Le floor ici c'est la fameux algorithme de regroupement.
    J'aurai pu l'écrire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CASE
      when c2 BETWEEN  0 AND  9 then 0
      when c2 BETWEEN 10 AND 19 then 1
      when c2 BETWEEN 20 AND 29 then 2
      else 3
    end
    D'où ma remarque, c'est plus rapide d'écrire une fonction quand il y a une logique de regroupement.

Discussions similaires

  1. Utilisation de MAX dans une requête SQL
    Par Evil onE dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/06/2004, 18h38
  2. Récupurer via une requête SQL la valeur la plus proche
    Par yoda_style dans le forum Langage SQL
    Réponses: 9
    Dernier message: 27/04/2004, 13h52
  3. Résultat d'une requète SQL
    Par camino dans le forum Bases de données
    Réponses: 2
    Dernier message: 21/02/2004, 15h22
  4. A propos d'une requête SQL sur plusieurs tables...
    Par ylebihan dans le forum Langage SQL
    Réponses: 2
    Dernier message: 14/09/2003, 16h26
  5. inverser la lecture d'une requète
    Par nilaco dans le forum Requêtes
    Réponses: 5
    Dernier message: 10/08/2003, 12h16

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