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 :

Vues avec plusieurs SELECT / avec plusieurs colonnes


Sujet :

SQL Oracle

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    238
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 238
    Points : 125
    Points
    125
    Par défaut Vues avec plusieurs SELECT / avec plusieurs colonnes
    Bonjour,
    j'aimerais savoir s'il était possible de créer une vue contenant plusieurs select (en tant que colonne) et SURTOUT que ces SELECT me ramènent plusieurs colonnes...
    Un exemple concret pour que cela soit plus clair :
    j'aimerais pour 2011 : 1 enregistrement par nom et prenom
    ainsi que (som) et (bdg) pour les 2 années précédentes

    Tous ces éléments se trouvent dans une MEME table/vue qui contient
    - Toujours un seul élément(nom/prénom) pour 2011,
    - Mais peut-être rien en 2010 et peut-être rien en 2009
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    create or replace view toto (nom,prenom,bdg_1,som_1,bdg_2,som_2) as
    select t.prenom,t.nom 
    ,(select bdg,som from table1 t1 where t.annee=t.annee-1 and rownum <2)
    ,(select bdg,som from table1 t2 where t.annee=t.annee-2 and rownum <2)
    from table1 t where t.annee=2011
    /
    J'ai une erreur à la création de la vue
    car j'indique plusieurs colonnes dans mes 2 derniers SELECT
    y-a-t'il un moyen de créer une vue ce ce genre ?
    Pour que cela fonctionne je dois dédoubler les 2 SELECT(Avec une seule colonne) ..PAS du tout perfomant!
    Surtout que ma vue finale va contenir une vingtaine de colonnes.

    Pouvez-vous m'aider ?
    Merci.

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    mets les sous select dans la clause FROM

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    238
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 238
    Points : 125
    Points
    125
    Par défaut
    je vais essayer,
    mais je n'ai accès à la base de données que lundi matin
    pourrais-je avoir un exemple concret/simple,
    car je n'ai jamais utilisé ce type de "mécanisme"
    dans la création de mes vues.
    Merci.

  4. #4
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Désolé, j'ai dit une connerie. Après avoir testé, ça ne marche pas (on ne peut pas référencer une autre table dans un sous select au niveau From.

    2 solutions : Soit une condition sur les 3 années, avec un decode et un group by, soit une concaténation bdg ||'.'|| som dans les sousrequêtes, et un split dans un select au dessus

    1ere solution (attention, A finir car on ne teste pas s'il existe une ligne en 2011)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT prenom, nom, 
    	max(decode(annee, 2009, bdg, NULL)) bdg_1, max(decode(annee, 2009, som, NULL)) som_1, 
    	max(decode(annee, 2010, bdg, NULL)) bdg_2, max(decode(annee, 2010, som, NULL)) som_2 
    FROM table1 
    WHERE annee BETWEEN 2009 AND 2011
    group by prenom, nom
    2ème solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select prenom, nom, substr(d1, 0, instr(d1, '.')-1) bdg1, substr(d1, instr(d1, '.')+1) som1, 
    				substr(d2, 0, instr(d2, '.')-1) bdg2, substr(d2, instr(d2, '.')+1) som2
    from (
    	SELECT t.prenom,t.nom,(SELECT bdg ||'.'|| som FROM table1 t1 WHERE t.annee=t.annee-1 AND rownum <2) d1
    		,(SELECT bdg ||'.'|| som FROM table1 t2 WHERE t.annee=t.annee-2 AND rownum <2) d2
    	FROM table1 t WHERE t.annee=2011
    	)

  5. #5
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    La requête scalaire ne peut ramener qu'une seule valeur d’une seule colonne. Il est très facile de contourner cette restriction en utilisant des types objet mais ce n’est pas très performant. Mais comme ce type de requête est équivalent à un outer join il suffit donc de l’utiliser:
    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
     
    With Data As (
      SELECT prenom, nom, annee, Max(bdg) As dgb, Max(bdg) As som
        FROM table1 t1 
       Group By prenom, nom, annee
    )
    SELECT t.prenom,t.nom, 
           t_1.bdg, t_1.som,
           t_2.bdg, t_2.som
      FROM table1 t 
           Left Outer Join
           Data t_1
        On t.annee = t_1.annee-1
           And t.nom = t_1.nom
           And t.prenom = t_1.prenom
           Left Outer Join
           Data t_2
        On t.annee = t_1.annee-2
           And t.nom = t_2.nom
           And t.prenom = t_2.prenom           
     WHERE t.annee=2011
    /
    Mais faite attention à la signification des vos rownum < 2.

  6. #6
    Membre émérite Avatar de Drizzt [Drone38]
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2004
    Messages
    1 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 001
    Points : 2 453
    Points
    2 453
    Par défaut
    Avec une fonction analytique sinon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select prenom, nom, bdg1, som1, bdg1, bdg2 
    from (
        select prenom, nom,
               lag(bdg,1) over(partition by prenom, nom order by annee) bdg1,
               lag(som,1) over(partition by prenom, nom order by annee) som1,
               lag(bdg,2) over(partition by prenom, nom order by annee) bdg2,
               lag(som,2) over(partition by prenom, nom order by annee) som2,
               annee
        from table1 
        where annee between 2011-2 and 2011
    ) where annee = 2011

    Edit> Attention cette requête est incorrecte si il y a des trous dans la présence des données depuis 2011 (ex: données en 2011 et 2009 mais pas 2010). Par contre cela fonctionne si les données les plus récentes sont présentes (ex: données en 2011 et 2010 mais pas 2009).

  7. #7
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Ta requête ne fonctionne que si la clé c'est "nom, prenom, année", si jamais tu as mois en plus dans la clé, ça ne marchera pas.

  8. #8
    Membre émérite Avatar de Drizzt [Drone38]
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2004
    Messages
    1 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 001
    Points : 2 453
    Points
    2 453
    Par défaut
    Oui mais ce n'est pas précisé dans l'énoncé et il est facile de l'adapter si la clef est différente.

  9. #9
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Je ne suis pas sur.
    De plus selon l'énoncé, une des années peut ne rien ramener comme données, dnas ce cas, le lag(1) ne va pas ramener la bonne année.

  10. #10
    Membre émérite Avatar de Drizzt [Drone38]
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2004
    Messages
    1 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 001
    Points : 2 453
    Points
    2 453
    Par défaut
    Je ne vois vraiment pas en quoi l'ajout du mois peut gener.
    Je viens de faire un test (rapide, dans un cas nominal uniquement) et je peux sans souci remonter les valeurs des années 2010 et 2009 pour chaque mois de 2011 traité.

    Par contre tu as raison si il manque des données en 2010.
    J'avais testé avec des données manquantes en 2009, mais pas ce cas.

    A voir donc si ce cas est fonctionnellement possible dans le cas de l'auteur mais je vais ajouter la restriction sur mon post.
    Merci à toi pour la remarque.

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/08/2007, 16h07
  2. Réponses: 8
    Dernier message: 16/02/2007, 12h53
  3. plusieur select avec le meme nom
    Par oughlad dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 26/05/2006, 12h09
  4. Problème pour différencier plusieurs select avec le même nom
    Par vallica dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 24/04/2006, 11h35
  5. selection de plusieurs dates avec un calandrier
    Par matdesign dans le forum Access
    Réponses: 5
    Dernier message: 01/10/2005, 08h21

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