Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2007
    Messaggi
    12

    Trasposizione Righe in Colonne

    Ho una select che mi restituisce questi risultati:
    azienda matricola
    0101233 IT007000001249
    0101233 IT007020001525
    0101417 IT007000001810
    0101417 IT007000004786
    0119647 IT007000004119
    0119647 IT007000004787
    0119647 IT007020004080
    0223021 IT018005100754
    0223021 IT013000453456
    0223021 IT018005100776
    0921434 IT018000000303
    0921434 IT018000000299
    0921434 IT018000002436
    0921434 IT016000049815
    0921434 IT012000022684
    0930405 IT017004901212
    0930405 IT017004901213
    0930405 IT017004901202

    .... ecc. ecc.

    Ora dovrei "trasporre", per ogni "azienda", le righe in colonne ottenendo questo risultato, sempre tramite T_Sql:

    azienda matricola matricola matricola matricola matricola
    0101233 IT007000001249 IT007020001525
    0101417 IT007000001810 IT007000004786
    0119647 IT007000004119 IT007000004787 IT007020004080
    0223021 IT018005100754 IT013000453456 IT018005100776
    0921434 IT018000000303 IT018000000299 IT018000002436 IT016000049815 IT012000022684
    0930405 IT017004901212 IT017004901213 IT017004901202

    .... ecc. ecc.

    Le colonne, nel mio caso, saranno esattamente massimo 5, grazie all'aiuto di "comas17" che mi ha aiutato a selezionare un massimo 5 righe per ogni "azienda"
    Pensavo di poter utilizzare PIVOT e invece niente .... sono nei guai; per martedì il mio capo vuole vedere questo risultato, e io non saprei più cosa provare.

  2. #2
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,372
    Puoi postare la query che hai fatto con pivot ?
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    1,317
    ma devi farlo per forza con sql? non puoi lavorare con gli array con il tuo linguaggio?

  4. #4
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,372
    Prova cosi (ho copiato le 18 righe che hai postato). La mia tabella si chiama toto (cioè pippo in Francese )
    Forse ci sono altri metodi ma un paio di ore fa erano 15 anni che non usavo sql server.

    codice:
    with a (az,mat,row_) as ( 
     SELECT azienda, matricola, ROW_NUMBER() OVER (ORDER BY azienda) as row_ FROM toto
    ),
    b (az, amin, amax) as (
    select az, min(row_) as amin, max(row_) as amax from a group by az
    ),
    c (az, amin, amax, mat) as (
    select a.az, amin, amax, mat from b, a
    where a.row_ between amin and amax
    ),
    d (az, mat, pos) as (
    select c.az, c.mat, row_ - amin + 1 as pos from c,a 
    where c.az = a.az and c.mat = a.mat
    ),
    primo   (az, mat1) as (select az, mat from d where pos = 1),
    secondo (az, mat2) as (select az, mat from d where pos = 2),
    terzo   (az, mat3) as (select az, mat from d where pos = 3),
    quarto  (az, mat4) as (select az, mat from d where pos = 4),
    quinto  (az, mat5) as (select az, mat from d where pos = 5)
    select primo.az, mat1, mat2, mat3, mat4, mat5 from primo
    left join secondo on secondo.az = primo.az
    left join terzo   on terzo.az   = secondo.az
    left join quarto  on quarto.az  = terzo.az
    left join quinto  on quinto.az  = quarto.az


    codice:
    az      mat1           mat2           mat3           mat4           mat5
    0101233 IT007000001249 IT007020001525 NULL           NULL           NULL
    0101417 IT007000001810 IT007000004786 NULL           NULL           NULL
    0119647 IT007000004119 IT007000004787 IT007020004080 NULL           NULL
    0223021 IT018005100754 IT013000453456 IT018005100776 NULL           NULL
    0921434 IT018000000303 IT018000000299 IT018000002436 IT016000049815 IT012000022684
    0930405 IT017004901212 IT017004901213 IT017004901202 NULL           NULL
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  5. #5
    Se puoi creare ed usare le function e le table-valued di sql server , la cosa
    è fattibile anche se probabilmente non sarà velocissima se i record sono molti.

    Ti crei una function che restituisce una table

    codice:
    CREATE FUNCTION dbo.fn()
    RETURNS @t TABLE (
       Azienda int NOT NULL,
       mat1 varchar(4),
       mat2 varchar(4),
       mat3 varchar(4),
       mat4 varchar(4),
       mat5 varchar(4)
    ) 
    AS
    BEGIN
    
    /*
    
    1) qui dichiari e popoli (INSERT INTO) un'altra table , che  battezziamo con il nome @topn , con 
    i campi di cui alla tua discussione precedente "select top n"  e - nota bene - *compreso il rowid* 
    
    2) in @t inserisci  tutte le aziende *distinte* che si trovano in @topn
    
    3) aggiorni i campi mat<X>  di @t con il campo matricola di @topn con le condizioni
       @t.azienda=@topn.azienda e @topn.rowid=<X>;
    
      usa una query di update come segue :
    
       	update @t	set matX=t.matricola
    	from @t as qx inner join @topn as t
    	on qx.idazienda= .... and ....
    */
    
     -- finito
     RETURN;
    
    END
    a questo punto potrai vedere il risultato desiderato eseguendo :

    select * from dbo.fn()

    HTH

  6. #6
    Utente di HTML.it L'avatar di nman
    Registrato dal
    Jan 2011
    residenza
    Milano
    Messaggi
    1,333
    Caspita dopo avere finito di scrivere (con sudore) il codice
    faccio per postare e scopro che è ormai troppo tardi
    sono stato preceduto

    Comunque con la mia scarsità avrei fatto cosi (avendo letto anche il precedente thread )
    ( PS, dopo vado a "studiarmi" le proposte di sspintux e badaze )

    data questa tabella:
    codice:
    -- Uso Master
    USE [master]
    GO
    --    Creo un DB
    CREATE DATABASE [Test5]
    GO
    --   Uso il DB appena creato
    USE [Test5]
    GO
    --  Creo una tabella   T1   molto semplice senza Key o altro
    CREATE TABLE [dbo].[T1]
    ( 
     [Azi] [nvarchar](50) NULL,
     [Mat] [nvarchar](50) NULL 
    ) ON [PRIMARY]
    GO
    --  Inserisco i dati in tabella 
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'06')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'02')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'03')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'07')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'05')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'08')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'aaa', N'09')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'bbb', N'20')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'bbb', N'17')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'bbb', N'12')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'bbb', N'18')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'bbb', N'01')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'bbb', N'02')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ccc', N'22')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ccc', N'21')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ccc', N'24')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'02')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'03')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'01')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'07')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'08')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'ddd', N'04')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'eee', N'02')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'eee', NULL)
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'eee', N'07')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'eee', N'01')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'eee', N'12')
    GO
    INSERT [dbo].[T1] ([Azi], [Mat]) VALUES (N'eee', N'14')
    GO

    applico questa query

    codice:
    --   Uso Test5
    USE [Test5]
    GO
    WITH
     
    Vis1 AS
    (
    SELECT     
    Azi, Mat, 
    ROW_NUMBER() OVER (PARTITION BY Azi ORDER BY Mat) AS RN
    FROM dbo.T1
    ),
    Vis2 AS
    (
    SELECT TOP (100) PERCENT 
    Azi, Mat, RN
    FROM Vis1
    WHERE (RN < 5.5)
    ORDER BY Azi, Mat
    ),
    Vis3 AS
    (
    SELECT     
    Azi, 
    MAX(CASE WHEN RN = 1 THEN Mat END) AS e1, 
    MAX(CASE WHEN RN = 2 THEN Mat END) AS e2, 
    MAX(CASE WHEN RN = 3 THEN Mat END) AS e3, 
    MAX(CASE WHEN RN = 4 THEN Mat END) AS e4, 
    MAX(CASE WHEN RN = 5 THEN Mat END) AS e5
    FROM Vis2
    GROUP BY Azi
    ),
    Vis4 AS
    (
    SELECT     
    Azi, 
    (CASE WHEN (e1 IS NULL) THEN N'' ELSE e1 END) + (CASE WHEN (e2 IS NULL) THEN N'' ELSE (N'/' + e2) END) + (CASE WHEN (e3 IS NULL) THEN N'' ELSE (N'/' + e3) END) + (CASE WHEN (e4 IS NULL) THEN N'' ELSE (N'/' + e4) END) + (CASE WHEN (e5 IS NULL) THEN N'' ELSE (N'/' + e5) END) AS Res
    FROM Vis3
    )
    
    SELECT * FROM Vis4

    Osserva che se al campo "Mat" ( matricola ) hai dei valori NULL oppure stringhe a lunghezza zero questi ti occupano comunque i primi posti dei tuoi 5


    Pero concordo con zacca94 quando ti fa notare che sarebbe meglio spostare la query a lato applicazione.


    .
    Ultima modifica di nman; 07-12-2014 a 02:10

  7. #7
    Quote Originariamente inviata da nman Visualizza il messaggio
    ...
    avrei fatto cosi (avendo letto anche il precedente thread )
    .....

    .
    ... allora aggiungiamone anche un'altra più leggibile che fa uso delle CTE
    e compendia sia la TOP N che la Traslazione dele righe in colonne

    codice:
    use tempdb
    go
    
    
    -- Tabella di partenza
    if OBJECT_ID('t') is not null drop table t
    go
    create table t (IDAz int, mat varchar(4))
    insert into t (IDAz,Mat) values (1,'m11')
    insert into t (IDAz,Mat) values (1,'m12')
    insert into t (IDAz,Mat) values (1,'m13')
    insert into t (IDAz,Mat) values (1,'m14')
    insert into t (IDAz,Mat) values (1,'m15')
    insert into t (IDAz,Mat) values (1,'m16')
    insert into t (IDAz,Mat) values (1,'m16')
    
    
    insert into t (IDAz,Mat) values (2,'m21')
    insert into t (IDAz,Mat) values (2,'m22')
    insert into t (IDAz,Mat) values (2,'m23')
    
    
    insert into t (IDAz,Mat) values (3,'m31')
    insert into t (IDAz,Mat) values (3,'m32')
    
    
    go
                  
    with 
     b (idaz,mat,rowid) as
    ( 
      select q.IDAz,q.mat,q.rowid 
      from (
    	    select IDAz,mat, 
    	           ROW_NUMBER() OVER (PARTITION BY idaz ORDER BY mat) as rowid 
    	    FROM  t
    	   ) q
      where q.rowid<=5
     ),
     a(idaz) as
     ( 
      select distinct IDAz from b
     )
    select  a.idaz
           ,(select b.mat from b where b.IDAz=a.idaz and b.rowid=1) as mat1 
           ,(select b.mat from b where b.IDAz=a.idaz and b.rowid=2) as mat2 
           ,(select b.mat from b where b.IDAz=a.idaz and b.rowid=3) as mat3 
           ,(select b.mat from b where b.IDAz=a.idaz and b.rowid=4) as mat4 
           ,(select b.mat from b where b.IDAz=a.idaz and b.rowid=5) as mat5 
    from a

  8. #8
    Utente di HTML.it
    Registrato dal
    Jun 2007
    Messaggi
    12
    OK, ho fatto mia la soluzione proposta da "badaze", il primo che mi ha risposto (disarmante nella sua semplicità), ma anche le altre mi sembrano (nel mio piccolo) niente male e sicuramente le approfondirò.
    Ragazzi, vi ringrazio tutti quanti .... non potete capire quanto mi siete stati utili e probabilmente, non dico che mi avete salvato il c.lo ... ma quasi.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.