Oracle 10 - multiple lignes pour même id

Oracle 10 - multiple lignes pour même id - SQL/NoSQL - Programmation

Marsh Posté le 23-11-2009 à 09:45:32    

Bonjour,
 
Je vais essayer d'expliquer mon problème simplement... :
 
Soit deux tables
 
TABLE PERSONNE

Code :
  1. ID,nom
  2. 1 toto
  3. 2 tata
  4. 3 titi


 
et
 
TABLE VALEURS

Code :
  1. ID_PERS propriété valeur
  2. 1 | age       | 20
  3. 1 | adresse | rue des fleurs
  4. 2 | age      | 29
  5. 1 | ville| PARIS
  6. 3 | adresse | rue


 
Mon but est de récupérer des résultats comme :

Code :
  1. 1 | toto | 20    | rue des fleurs | PARIS
  2. 2 | tata | 29    | (null) |            (null)
  3. 3 | titi  | (null) | rue     |            (null)


 
Cela j'y arrive avec des requêtes comme :
 

Code :
  1. SELECT ID,NOM,
  2. (SELECT valeur from TABLE_VALEURS WHERE ID_PERS=ID AND type='age'),
  3. (SELECT valeur from TABLE_VALEURS WHERE ID_PERS=ID AND type='adresse'),
  4. (SELECT valeur from TABLE_VALEURS WHERE ID_PERS=ID AND type='ville')
  5. FROM PERSONNE;


 
Cela fonctionne quand j'ai un seul 'age', un seul 'adresse' par PERSONNE. Quand il y a plusieurs adresses, j'ai plusieurs lignes retournées, la requête échoue donc. C'est normal.
Solution : rajouter AND rownum=1 à chaque sous requête.
 
Problème : je n'ai qu'une seule valeur retournée que je ne choisis pas.
 
Question : Comment faire pour retourner toutes les valeurs en répétant les Personnes ?
Comme :
 

Code :
  1. 1 | toto | 20    | rue des fleurs | (null)
  2. 1 | toto | 20    | chemin des peupliers | (null)
  3. 1 | toto | 20    | (null) | PARIS
  4. 1 | toto | 20    | (null) | MARSEILLE
  5. 2 | tata | 29    | (null) |            (null)
  6. 3 | titi  | (null) | rue     |            (null)


 
(exemple : 2 adresses et deux villes)
 
Merci d'avance et merci déjà d'avoir lu mon problème !


Message édité par ___ le 23-11-2009 à 09:49:59
Reply

Marsh Posté le 23-11-2009 à 09:45:32   

Reply

Marsh Posté le 23-11-2009 à 10:39:04    

ca ca fait ce que tu veux mais ton modèle de donnée est a pleurer, genre y a rien qui te dit a quelle ville appartient la rue?
 

Code :
  1. SELECT ID,NOM,valeur, NULL,NULL
  2. FROM PERSONNE
  3. INNER JOIN TABLE_VALEURS WHERE ID_PERS=ID AND type='age'
  4. union ALL
  5. SELECT ID,NOM,NULL,valeur,NULL
  6. FROM PERSONNE
  7. INNER JOIN TABLE_VALEURS WHERE ID_PERS=ID AND type='adresse'
  8. union ALL
  9. SELECT ID,NOM,NULL,NULL,valeur
  10. FROM PERSONNE
  11. INNER JOIN TABLE_VALEURS WHERE ID_PERS=ID AND type='ville'


Reply

Marsh Posté le 23-11-2009 à 10:58:52    

Salut,
merci pour ta réponse.
 
Bon ok pour le modèle de données, j'ai adapté mon cas  avec un exemple pas forcément pertinent (ville,adresse). Imaginons plutôt des téléphones et emails multiples ;-)
 
J'ai adapté ton exemple à mon cas (attention, c'est ON et pas WHERE) et j'obtiens ce que je pensais, par contre, j'obtiens 2 lignes pour les couples (age,adresse = null,adr1 et 20,null) par exemple
or ces valeurs pourraient tenir sur la même ligne.
 
Peut être n'est-ce pas possible dans la même requête d'avoir ces "conditions", ou alors une astuce me le permettrait ?

Reply

Marsh Posté le 23-11-2009 à 11:13:49    

___ a écrit :

Salut,
merci pour ta réponse.
 
Bon ok pour le modèle de données, j'ai adapté mon cas  avec un exemple pas forcément pertinent (ville,adresse). Imaginons plutôt des téléphones et emails multiples ;-)
 
J'ai adapté ton exemple à mon cas (attention, c'est ON et pas WHERE) et j'obtiens ce que je pensais, par contre, j'obtiens 2 lignes pour les couples (age,adresse = null,adr1 et 20,null) par exemple
or ces valeurs pourraient tenir sur la même ligne.
 
Peut être n'est-ce pas possible dans la même requête d'avoir ces "conditions", ou alors une astuce me le permettrait ?


 
Si ton modèle de données n'était pas si mauvais, ça marcherait tout seul.
Tu dois pouvoir récupérer tout ça via un truc du style
 

Code :
  1. SELECT id, nom, max(colonne1), max(colonne2), ...
  2. FROM( [ta requete actuelle] )
  3. GROUP BY id, nom


 
...mais c'est franchement hideux de toute manière...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 11:16:33    

+1
au lieu d'empiler des requêtes bizzaroïdes et des données en spaguettis, repose toi la question sur ton modèle de données, car sinon tu passeras ton temps à contourner le problème via des bidouilles et ca donnera un truc pas facilement maintenable

Reply

Marsh Posté le 23-11-2009 à 11:23:03    

La réponse de Skeye me convient,merci.
MODIF : non, en fait je perds les valeurs multiples... !
 
 Les données en spagettis sont utiles dans ma base, cela me permet d'ajouter autant de propriétés que je souhaite à une personne ;-)
 
Donc oui cela donne un schéma plus compliqué mais dans mon appli, cela en vaut la chandelle.
Merci à tous

Message cité 1 fois
Message édité par ___ le 23-11-2009 à 11:25:44
Reply

Marsh Posté le 23-11-2009 à 11:35:37    

___ a écrit :

La réponse de Skeye me convient,merci.
MODIF : non, en fait je perds les valeurs multiples... !


 
tu peux pas avoir le beurre, l'argent du beurre et le cul de la crémière...tu n'auras pas à la fois toutes tes valeurs et tout sur une ligne...
 

___ a écrit :

Les données en spagettis sont utiles dans ma base, cela me permet d'ajouter autant de propriétés que je souhaite à une personne ;-)
 
Donc oui cela donne un schéma plus compliqué mais dans mon appli, cela en vaut la chandelle.


Non, ça n'en vaut pas la chandelle du tout.
Ton schéma n'est pas compliqué, il est absurde...tout mettre en vrac dans une table est la pire chose à faire dans un design de bdd.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 11:36:07    

Dans ce cas, autant ajouter une propriété "nom" dans la table "valeurs" et se passer de la table "personne", au cas où la personne aurait plusieurs noms aussi, vu qu'elle peut déjà avoir plusieurs âges :) Pour ajouter une propriété unique à un record, il y a un truc qui s'appelle "ALTER TABLE".
 
Le principe des propriétés multiples en soi n'est pas idiot mais alors il faudrait idéalement utiliser une autre table "propriétés" listant les propriétés existantes avec pour chacune un id et un libellé, id qu'on utilisera à la place du libellé pour la colonne "propriété" de la table valeurs.

Reply

Marsh Posté le 23-11-2009 à 11:39:30    

cbeyls a écrit :

Dans ce cas, autant ajouter une propriété "nom" dans la table "valeurs" et se passer de la table "personne", au cas où la personne aurait plusieurs noms aussi, vu qu'elle peut déjà avoir plusieurs âges :) Pour ajouter une propriété unique à un record, il y a un truc qui s'appelle "ALTER TABLE".
 
Le principe des propriétés multiples en soi n'est pas idiot mais alors il faudrait idéalement utiliser une autre table "propriétés" listant les propriétés existantes avec pour chacune un id et un libellé, id qu'on utilisera à la place du libellé pour la colonne "propriété" de la table valeurs.


 
Non mais faut arrêter de fumer les enfants hein, si tu veux qu'une personne puisse avoir plusieurs adresses, tu as une table des adresses, une table des personnes, et une table faisant le lien, point barre.
Et l'âge d'une personne ça ne se stocke pas, ce qu'on stocke c'est une date de naissance. Et c'est un champ de la table personne, pas autre chose.
Bref, une base de données c'est censé stocker des données structurées, c'est pas là pour tout ranger en bordel et essayer de sortir ce qu'on veut en bidouillant plus tard...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 11:41:02    

Concernant le schéma, je reprécise que je l'ai simplifié pour les exemples.
 
cbeyls->J'ai en effet une table de propriétés :-)
 
Le nom est aussi une propriété en vrai (et j'autorise ou non les propriétés à etre multiples ou pas).
 
skeye : ce n'est pas absurde, imagine un client me demande d'ajouter une propriété "nombre de spaghettis mangées", toi tu dois faire un alter + changer le formulaire de la personne. Moi j'ai juste à ajouter la propriété, le formulaire est ajouté automatiquement.
Et bien sûr que je ne stocke pas l'âge  ce sont des données d'exemple !!! ;-)

Message cité 1 fois
Message édité par ___ le 23-11-2009 à 11:41:56
Reply

Marsh Posté le 23-11-2009 à 11:41:02   

Reply

Marsh Posté le 23-11-2009 à 11:43:58    

___ a écrit :


Le nom est aussi une propriété en vrai (et j'autorise ou non les propriétés à etre multiples ou pas).
skeye : ce n'est pas absurde


 
[:prozac]
Tu es l'exemple parfait du type qui croit qu'il a eu une idée géniale, mais fait de la merde.[:dawak]
Il te reste quoi dans ta table personne, un id auto-généré et c'est tout?[:dawak]
 
Rien ne t'empêche de faire ce que tu fais pour quelques propriétés "aléatoires".
Faire ça pour tout c'est juste le comble de la bêtise.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 11:48:35    

...et ressentir le besoin de récupérer des données en ligne au lieu de colonnes est un signe très clair d'une archi mal branlée...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 11:51:52    

Non, ce principe est adapté à mes besoins. L'idée (pas la mienne) me paraissait aussi mauvaise question organisation (j'avais les mêmes à-prioris que toi) mais à l'utilisation je trouve cela aujourd'hui parfait pour mes besoins.
Cette récupération en ligne est destinée à un utilisateur lambda, donc c'est normal.
;-)

Reply

Marsh Posté le 23-11-2009 à 11:52:58    

___ a écrit :

Cette récupération en ligne est destinée à un utilisateur lambda, donc c'est normal.
;-)


En temps normal c'est pas le boulot de SQL de formatter les données...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 11:53:38    

Il y a plus simple, the ultimate modele de la mort :
Table (nom)
Colonne(Table, NomColonne, Valeur)
Et tu stocke toutes tes donnees dedans. Bien sur ca va etre un peu merdique a relire, mais c'est formidable, tu peux aussi bien gerer des stocks que des impots, des emails, du contenu web...
 
Sinon, il est plus simple de faire une vraie modelisation, mais c'est comme tout, ca necessite du travail.

Reply

Marsh Posté le 23-11-2009 à 11:56:54    

fred777888999 a écrit :

Il y a plus simple, the ultimate modele de la mort :
Table (nom)
Colonne(Table, NomColonne, Valeur)


 
C'est cela mon schéma ;-)
 
En temps normal c'est pas le boulot de SQL de formatter les données...
=> j'essaie de le faire dans une requete pour tenter d'avoir les résultats rapidement sans traitement lourd en PHP après. Mais si il le faudra... je ferai le tout en scripts avec plusieurs requêtes.

Reply

Marsh Posté le 23-11-2009 à 12:00:16    

___ a écrit :


 
C'est cela mon schéma ;-)


 
[:prozac]²²²²²²²²²²²
 

___ a écrit :

j'essaie de le faire dans une requete pour tenter d'avoir les résultats rapidement sans traitement lourd en PHP après. Mais si il le faudra... je ferai le tout en scripts avec plusieurs requêtes.


 
t'as pas besoin de plusieurs requêtes. La seule dont tu as besoin c'est  
 

Code :
  1. SELECT * FROM table_valeurs WHERE id = toto AND type IN (type1, type2, ..., typen)


 
Le reste c'est du passage de lignes en colonnes, ça se fait dans le langage qui va traiter les données.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 12:14:45    

...au passage j'adore l'ironie du concept de la recherche de perfs, avec une archi de bdd stockant tout (lire : potentiellement quelques millions de lignes) dans la même table et empêchant l'utilisation du moindre index utile (à part sur la colonne "type"...supair [:dawa]).[:moule_bite]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 23-11-2009 à 22:22:14    

Pour info j'étais ironique dans ma réponse :) Ben sûr que c'est ridicule d'avoir plusieurs ages ou noms et tout mélanger dans un foutoir... Pourquoi, parce que ça rend le code le code super compliqué et illisible d'une part et ça ralentit les performances d'autre part, et en plus ça t'autorise à faire à peu près n'importe quoi ce qui fait qu'un jour tu risques de te retrouver avec des données incohérentes et inutilisables ("ha ben mince la personne a plusieurs sexes, homme et femme, c'est lequel le bon?" ).
 
La table des propriétés ça s'applique bien à quelques rares cas quand c'est fait de façon correcte, par exemple un système de "tags" sur les articles d'un blog, mais ça doit se limiter au minimum et cibler une application précise au lieu de les mélanger. Donc dans ton cas, tu pourrais créer une table adresse pour les personnes qui ont plusieurs adresses, mais elle doit être dédiée uniquement aux adresses. En règle générale, plus tu mets de contraintes, mieux c'est.


Message édité par cbeyls le 23-11-2009 à 22:24:54
Reply

Marsh Posté le 24-11-2009 à 09:21:18    

Lol
Le débat est costaud :-D
 
C'est clair qu'il ne faut pas tout poser en vrac dans une table de propriétés. Mais dès qu'on veut être dynamique et pouvoir changer à la volée ses propriétés, ce système est plutôt efficace.
 
Pour mon problème d'origine, j'ai finalement fait un traitement PHP qui me formate comme je le souhaite mes données.
 
merci à tous d'avoir participé !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed