[SQL] Passé de lignes à collones, possible ?

Passé de lignes à collones, possible ? [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 22-12-2006 à 11:50:55    

Bonjour la compagnie :hello:
 
Deja bonne fêtes de fin d'année a tous ! (si possible ailleurs qu'au boulot :D)
 
J'ai une chtite question a propos d'une requête que je n'arrive pas a matérialiser, voici le principe :
 
J'ai un user qui appartient a plusieurs communautés donc dans la table sa donne :
 
user 1 | communauté1
user 1 | communauté2
user 1 | communauté3
user 2 | communauté1
user 2 | communauté7
 
Et j'aimerais obtenir ceci avec une requete en :
 
Iduser | communauté1 | communauté2 | communauté3 | communauté4 | communauté5 | communauté6 | communauté7 |  
______________________________________________________________________________________________________
user 1 |        OUI        |      OUI         |     OUI           |         NON      |         NON      |         NON      |         NON      |
user 2 |        OUI        |      NON        |     NON          |         NON      |         NON      |         NON      |         OUI       |
 
Sachant qu'il existe au maximum 40 communautés, donc au lieu de 7 il yaura 40 collones
 
Une idée sur la requete ?
 
Merci d'avance :jap:


Message édité par hassbak le 22-12-2006 à 11:51:40

---------------
Je vous préviens, je suis une merde en orthographe, vous me parlé à vos risques et périls !
Reply

Marsh Posté le 22-12-2006 à 11:50:55   

Reply

Marsh Posté le 22-12-2006 à 11:52:40    

J'ai une question con : t'en fais quoi, après de ta requête?[:autobot]

Message cité 1 fois
Message édité par skeye le 22-12-2006 à 11:52:53

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

Marsh Posté le 22-12-2006 à 13:08:31    

skeye a écrit :

J'ai une question con : t'en fais quoi, après de ta requête?[:autobot]


 
Je la fou tel quel dans un fichier excel :)
 
Apres je sais pas ce qu'ils en font, c'est plus mon problème :)

Reply

Marsh Posté le 22-12-2006 à 13:22:04    

salut,
ca a déjà été traité ici http://forum.hardware.fr/hfr/Progr [...] 8586_1.htm
et ici http://forum.hardware.fr/hfr/Progr [...] 8671_1.htm
ca pourra peut-etre t'aider

Reply

Marsh Posté le 22-12-2006 à 15:48:07    

sgbd ? :spamafote:

Reply

Marsh Posté le 22-12-2006 à 16:38:19    

SQL SERVER 2005
 
J'ai regardé les exemples et sa ne m'a pas vraiment aidé
 
En fait je crois que je vais devoir passé par une ecriture dynamique de la requête SQL
 
Car je résume :
 
 
1°) Table de communauté :
 
id | lib
1    Communauté1
2    Communauté2
3    Communauté3
4    Communauté4
 
2°) Table des utilisateurs
 
id_user | id_communauté
PAUL         1
PAUL         3
MARC        2
BOB          1
BOB          4
 
3°) Ce que je voudrais
 
id_user |  Communauté1  |  Communauté2  |  Communauté3  | Communauté4
PAUL             OUI                   NON                   OUI                 NON
MARC            NON                   OUI                   NON                 NON
BOB              OUI                   NON                   NON                 OUI
 
Donc en gros les collones de ce que je veut (3°) sont variables selon le contenu de la table de communauté (1°)
Et le must serais tout de même que le libellé des collones du 3°) porte le nom du libellé de la communauté dans sa table
 
 
Donc je pense que sa doit être construit dynamiquement, mais je ne sais pas encore comment  :pt1cable:


Message édité par hassbak le 22-12-2006 à 16:41:36

---------------
Je vous préviens, je suis une merde en orthographe, vous me parlé à vos risques et périls !
Reply

Marsh Posté le 22-12-2006 à 16:48:30    

la fonction pivot_table est ton amie, et c'est une nouveauté de SQL Server 2005

Reply

Marsh Posté le 22-12-2006 à 16:50:31    

Oui je viens de voir ca sur google, j'essaye de me documenter un peu la :)
 
J'éspère solutioner ce problème rapidement :)
 
T'es un bon en SQL , chaque fois que j'ai eut un soucis, c'est toi qui a répondu !

Reply

Marsh Posté le 22-12-2006 à 17:18:47    

En fait finalement je pense pas que sa fonctionne
 
J'ai tenté le coup et d'une je ne sais pas utilisé PIVOT quand il ne s'agit pas de faire des sommes.
Dans mon cas pas la peine de faire de SUM
 
Secondo je ne sais pas combien de colonnes j'aurais, car elles dependent de la table Numero 1°)
 
Je me trompe ? :??:

Reply

Marsh Posté le 22-12-2006 à 18:02:26    

je ne connais pas du tout cette fonction.
j'ai juste vu ça dans la doc un coup alors que je cherchais autrechose, donc je ne me suis pas attardé dessus.
sous access en tout cas (mais aussi dans Excel) une table de pivot sert pourtant bel et bien à transformer des lignes en colonnes, en ajoutant une nouvelle dimension.

Reply

Marsh Posté le 22-12-2006 à 18:02:26   

Reply

Marsh Posté le 26-12-2006 à 09:57:31    

Up en ces jours de fêtes :)

Reply

Marsh Posté le 26-12-2006 à 17:01:38    

Bonjour,
As-tu envisagé de mettre d'abord sous excel puis de "mouliner" sur la feuille?
 
avec un sub de ce style:
Sub tralala()
'mettre toutes les colonnes à NON avant ou après
Worksheets("feuil1" ).Select
Set Wsht1 = Worksheets("feuil1" )
boubou = Wsht1.Cells(65536, 1).End(xlUp).Row
Set Wsht2 = Worksheets(2)
Range("a1" ).Select
Wsht2.Range("a1" ) = Wsht1.Range("a1" )
For i = 1 To boubou
    nom = Cells(i, 1)
    coco = Cells(i, 2)
    Set c = Wsht2.Range("A:A" ).Find(nom, LookIn:=xlValues)
    If Not c Is Nothing Then
        jinforme = c.Row
    Else
        fin2 = Wsht2.Cells(65536, 1).End(xlUp).Row + 1
        Wsht2.Cells(fin2, 1).Value = nom
        jinforme = fin2
    End If
    Wsht2.Cells(jinforme, 1 + coco) = "OUI"
Next i
End Sub
 
 
Cordialement
Sub tralala()
'mettre toutes les colonnes à NON avant ou après
Worksheets("feuil1" ).Select
Set Wsht1 = Worksheets("feuil1" )
boubou = Wsht1.Cells(65536, 1).End(xlUp).Row
Set Wsht2 = Worksheets(2)
Range("a1" ).Select
Wsht2.Range("a1" ) = Wsht1.Range("a1" )
For i = 1 To boubou
    nom = Cells(i, 1)
    coco = Cells(i, 2)
    Set c = Wsht2.Range("A:A" ).Find(nom, LookIn:=xlValues)
    If Not c Is Nothing Then
        jinforme = c.Row
    Else
        fin2 = Wsht2.Cells(65536, 1).End(xlUp).Row + 1
        Wsht2.Cells(fin2, 1).Value = nom
        jinforme = fin2
    End If
    Wsht2.Cells(jinforme, 1 + coco) = "OUI"
Next i
End Sub
 
 
Cordialement

Reply

Marsh Posté le 27-12-2006 à 13:24:32    

seniorpapou a écrit :

Bonjour,
As-tu envisagé de mettre d'abord sous excel puis de "mouliner" sur la feuille?
 
avec un sub de ce style:
Sub tralala()
'mettre toutes les colonnes à NON avant ou après
Worksheets("feuil1" ).Select
Set Wsht1 = Worksheets("feuil1" )
boubou = Wsht1.Cells(65536, 1).End(xlUp).Row
Set Wsht2 = Worksheets(2)
Range("a1" ).Select
Wsht2.Range("a1" ) = Wsht1.Range("a1" )
For i = 1 To boubou
    nom = Cells(i, 1)
    coco = Cells(i, 2)
    Set c = Wsht2.Range("A:A" ).Find(nom, LookIn:=xlValues)
    If Not c Is Nothing Then
        jinforme = c.Row
    Else
        fin2 = Wsht2.Cells(65536, 1).End(xlUp).Row + 1
        Wsht2.Cells(fin2, 1).Value = nom
        jinforme = fin2
    End If
    Wsht2.Cells(jinforme, 1 + coco) = "OUI"
Next i
End Sub
 
 
Cordialement
Sub tralala()
'mettre toutes les colonnes à NON avant ou après
Worksheets("feuil1" ).Select
Set Wsht1 = Worksheets("feuil1" )
boubou = Wsht1.Cells(65536, 1).End(xlUp).Row
Set Wsht2 = Worksheets(2)
Range("a1" ).Select
Wsht2.Range("a1" ) = Wsht1.Range("a1" )
For i = 1 To boubou
    nom = Cells(i, 1)
    coco = Cells(i, 2)
    Set c = Wsht2.Range("A:A" ).Find(nom, LookIn:=xlValues)
    If Not c Is Nothing Then
        jinforme = c.Row
    Else
        fin2 = Wsht2.Cells(65536, 1).End(xlUp).Row + 1
        Wsht2.Cells(fin2, 1).Value = nom
        jinforme = fin2
    End If
    Wsht2.Cells(jinforme, 1 + coco) = "OUI"
Next i
End Sub
 
 
Cordialement


+1 je pense que c'est la meilleure solution

Reply

Marsh Posté le 27-12-2006 à 13:32:01    

je n'ai quasi jamais touché a du sql server mais je suppose qu'il doit +/- offrir les memes possibilités que oracle au niveau sql dynamique, alors ce que je ferai dans un ps:
 
1) tu récuperes dans un curseur tous tes id distincts
2) tu fetchs le curseur en crééant dynamiquement le sql de ton create table style
 

Code :
  1. curseur is select distinct lib from communaute a,utilisateur b where a.id = b.id_communaute
  2. qry:= 'create table ma_table(nom_du_peye varchar2(100),'
  3. loop
  4.     qry:= qry || curseur.lib|| ' number,'
  5. end loop
  6. qry:= substr(qry,1,length(qry)-1) || ')'; -- pour virer la virgule en trop
  7. execute immediate qry


 
et tu executes ton sql, de nouveau en sql serveur faut pas me demander, mais l'equivalent oracle est execute immediate
 
3) tu inseres dans ta table les noms distincts des gars
 
4) tu updates chaque ligne en allant chercher dans une sous-requetes les valeurs, c'est pas du tout optimal comme méthode mais je suppose qu'on ne parle pas de millions de records, et il faut repasser par un loop des valeurs distinctes de communaute pour faire ca en sql dynamique.
 
style:
 

Code :
  1. curseur is select distinct lib from communaute a,utilisateur b where a.id = b.id_communaute
  2. loop
  3.     update ma_table ref set || curseur.lib || ' = nvl((select 1 from communaute a,utilisateur b where a.id = b.id_communaute
  4.                                                                 and b.utilisateur = ref.nom_du_peye
  5.                                                                 and a.lib = '|| curseur.lib || ' ),0)'
  6. end loop


 
     
ca devrait le faire
 
good luck

Reply

Marsh Posté le 27-12-2006 à 14:28:45    

J'ai utilisé une methode a peu pres equivalente a celle que tu viens de me conseiller et j'ai reussit a obtenir ce que je voulais
 
1°) Je recupere les id distinct de mes communautés et je creer une table avec
 
2°) J'utilise un curseur pour créer ma requete de pivot
 
3°) Je remplace les enregistrement en .Net, en disant si >0 alors Oui sinon Non
 
Et sa fonctionne
 
C'etais bien prise de tête
 
Merci a vous tous :jap:

Reply

Marsh Posté le 03-01-2007 à 12:00:37    

Salut , pourrais tu poster ton code s'il te plait car je suis dans le meme cas que toi , et je débute dans le sql.
 
Merci d'avance.


Message édité par Fr@chesco le 03-01-2007 à 12:00:49
Reply

Marsh Posté le 03-01-2007 à 13:47:37    

Je te post ca demain si je suis au bureau, parceque le jour de l'an a laissé quelque sequel sur ma personne :(

Reply

Marsh Posté le 04-01-2007 à 08:42:21    

Ok j'attend ca avec impatience :p !


Message édité par Fr@chesco le 04-01-2007 à 10:17:50
Reply

Marsh Posté le 10-01-2007 à 00:12:31    

bonjour,  
une petite solution qui peut peut etre fonctionner condition de connaitre le nombre de valeurs distinctes de communautés, ce qui est ton cas. Mais c'est un peu chiant à taper..
 
pour chaque colonne de communauté dans la  table de résultat, il faut faire une requete du style
case when utilisateurs.id_communaute=X then 1
else 0
end
 
ce qui donne par exemple pour 3 communautés distinctes :  
select U.ID, case when U.id_communaute=1 then 1
else 0
end
communaute1,
case when U.id_communaute=2 then 1
else 0
end
communaute2,
case when U.id_communaute=3 then 1
else 0
end
communaute3
 
puis il ne reste plus qu'a agréger ces lignes.
select ID, sum(communaute1),sum(ccommunaute2),sum(ccommunaute3) from (
select U.ID ID, case when U.id_communaute=1 then 1
else 0
end
communaute1,
case when U.id_communaute=2 then 1
else 0
end
communaute2,
case when U.id_communaute=3 then 1
else 0
end
communaute3
from utilisateurs U)
group by ID
 
en combinant cela avec un insert into, tu peux alimenter ta table, avec l'avantage de travailler en ensembliste.


Message édité par swich le 10-01-2007 à 00:18:18
Reply

Marsh Posté le 10-01-2007 à 09:33:20    

Inspire toi de cette procédure stockée :  
 
http://www.sqlteam.com/item.asp?ItemID=2955
 

Reply

Marsh Posté le 10-01-2007 à 10:03:29    

Voila celle que j'ai utilisé et qui fonctionne chez moi (inspiré d'un exemple sur le net)
 

Code :
  1. DECLARE @NumeroDeMois varchar(500) ,@NumeroDeProject varchar(500)
  2. SET @NumeroDeMois = ''
  3. DECLARE @ListeDesJours TABLE (IdJour varchar(500) )
  4. INSERT INTO @ListeDesJours (IdJour)
  5.    SELECT DISTINCT  c_value FROM tb_communautes
  6. DECLARE @Jours varchar(4000)
  7. SET @Jours = ''
  8. SELECT @Jours = @Jours + '[' + convert(varchar(500),IdJour) + '],'
  9. FROM @ListeDesJours
  10. SET @Jours = LEFT(@Jours, LEN(@Jours) - 1)
  11. EXEC( '
  12. DECLARE @RecapitulatifDesTemps TABLE
  13. (      Nom        varchar(500)
  14.       ,IdJour     varchar(500)
  15.       ,Duree      float
  16. )
  17. INSERT INTO @RecapitulatifDesTemps
  18. (
  19.        Nom       
  20.       ,IdJour   
  21.       ,Duree
  22. ) SELECT l_jh_id, l_c_id, l_jh_id FROM tb_listes_communautes
  23.       SELECT * FROM @RecapitulatifDesTemps
  24.              PIVOT (sum(Duree) FOR IdJour IN (' + @Jours + ')) PVT'
  25. )


Reply

Marsh Posté le 20-06-2007 à 15:33:23    

Salut, j'ai le même problème, je voudrais utiliser la fonction PIVOT pour transformer les colonnes en lignes, mais dans les exemples que j'ai trouvé il y a toujours utilisation de la somme SUM mais que dans mon cas c un pivot simple !
 
Merci d'avance.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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