none
Prodotto cartesiano RRS feed

  • Domanda

  • Buongiorno , 

    ho questa situazione: 

    Padre Figlio

    1 1_1

    1 1_2

    2 2_1

    2 2_2

    2 2_3

    Devo ottenere in output il seguente set di righe :

    1_1 2_1

    1_1 2_2

    1_1 2_3

    1_2 2_1

    1_2 2_2

    1_2 2_3

    Ovviamente se ci fosse una terza riga in padre dovrebbe esserci un'altra colonna con i risultati relativi...

    Mi date una mano?


    Carlo

    martedì 3 giugno 2014 12:45

Risposte

  • Ciao, 

    per fare quello che vuoi dovresti generare la query dinamicamente e poi eseguirla tramite una EXEC.

    Devi aprire un cursore sulla tabella padre e per ogni riga concatenare parti di SQL per arrivare all'istruzione finale. 

    DECLARE @idp VARCHAR(10)
    DECLARE @sqlselect VARCHAR(1000)
    DECLARE @sqlorderby VARCHAR(1000)
    DECLARE @sqlinnerselect VARCHAR(1000)
    
    DECLARE p CURSOR
    FOR
    SELECT intid
    FROM padre
    ORDER BY intid
    
    OPEN p
    
    FETCH NEXT
    FROM p
    INTO @idp
    
    WHILE @@fetch_status = 0
    BEGIN
    	SELECT @sqlselect = COALESCE(@sqlselect + ',', '') + 'tbl' + @idp + '.intid as [' + @idp + ']'
    
    	SELECT @sqlorderby = COALESCE(@sqlorderby + ',', '') + 'tbl' + @idp + '.intid'
    
    	SELECT @sqlinnerselect = COALESCE(@sqlinnerselect + ',', '') + '(select intidpadre, intid from figlio where intidpadre = ' + @idp + ') as tbl' + @idp
    
    	FETCH NEXT
    	FROM p
    	INTO @idp
    END
    
    CLOSE p
    
    DEALLOCATE p
    
    PRINT 'SELECT ' + @sqlselect + ' FROM ' + @sqlinnerselect + ' ORDER BY ' + @sqlorderby
    
    EXEC ('SELECT ' + @sqlselect + ' FROM ' + @sqlinnerselect + ' ORDER BY ' + @sqlorderby)
    


    • Contrassegnato come risposta Carlik mercoledì 4 giugno 2014 13:45
    mercoledì 4 giugno 2014 12:57

Tutte le risposte

  • Ciao, quello che vuoi ottenere è un prodotto cartesiano.

    Devi generare due tabelle a partire dalla tabella base con opportuni filtri (Padre=1 e Padre=2). Poi le metti in CROSS JOIN e dovresti ottenere il risultato voluto.

    Dai un'occhiata a questo link.

    CROSS JOIN

    Daniele

    martedì 3 giugno 2014 13:19
  • Non credo sia così semplice , perchè padre  non ha solo 2 "tipi" di righe... ne può avere 6,7,8... non c'è nulla per automatizzare il tutto?

    Carlo

    martedì 3 giugno 2014 13:47
  • Temo mi sta sfuggendo qualcosa della tua impostazione.

    In ogni caso ho provato a buttare giu un po' di codice. Il risultato è quello giusto? Puoi eventualmente postare il risultato voluto in caso di 3 o piu valori per il campo Padre? Giusto per capire.

    CREATE TABLE #temptbl (
    Padre INT
    ,Figlio VARCHAR(10)
    )
    
    INSERT INTO #temptbl
    VALUES (1,'1_1'),(1,'1_2'),(2,'2_1'),(2,'2_2'),(2,'2_3'),(3,'3_1'),(3,'3_2')
    
    SELECT T1.Figlio
    ,T2.Figlio
    FROM dbo.#temptbl AS T1
    ,dbo.#temptbl AS T2
    WHERE t1.Padre < t2.Padre
    ORDER BY t1.figlio

    Fammi sapere.

    Un abbraccio

    Daniele

    martedì 3 giugno 2014 15:35
  • In effetti mi sono spiegato molto molto male e chiedo scusa.

    Ecco qui uno script che riassume quello che voglio

    USE tempdb 
    
    CREATE TABLE Padre ( intID int )
    CREATE TABLE Figlio( intIDPadre int ,intId nvarchar(5) )
    
    INSERT INTO [tempdb].[dbo].[Padre] ([intID]) VALUES (1)
    INSERT INTO [tempdb].[dbo].[Padre] ([intID]) VALUES (2)
    INSERT INTO [tempdb].[dbo].[Padre] ([intID]) VALUES (3)
    
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (1, '1_1')
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (1, '1_2')
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (1, '1_3')
    
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (2, '2_1')
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (2, '2_2')
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (2, '2_3')
    
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (3, '3_1')
    INSERT INTO [tempdb].[dbo].[Figlio] ([intIDPadre] ,[intId]) VALUES (3, '3_2')
    
    --Risultato desiderato(la formattazione è un po' sballata)
    --col1	col2	        col3
    --1_1	2_1		3_1
    --1_1	2_2		3_1
    --1_1	2_3		3_1
    --1_1	2_1		3_2
    --1_1	2_2		3_2
    --1_1	2_3		3_2
    
    --1_2	2_1		3_1
    --1_2	2_2		3_1
    --1_2	2_3		3_1
    --1_2	2_1		3_2
    --1_2	2_2		3_2
    --1_2	2_3		3_2
    
    --1_3	2_1		3_1
    --1_3	2_2		3_1
    --1_3	2_3		3_1
    --1_3	2_1		3_2
    --1_3	2_2		3_2
    --1_3	2_3		3_2


    Carlo

    mercoledì 4 giugno 2014 07:41
  • Devo dedurre che se ci fosse un padre 4 vorresti che nel risultato ci fosse una quarta colonna e cosi via...?
    mercoledì 4 giugno 2014 08:51
  • si....

    Carlo

    mercoledì 4 giugno 2014 09:04
  • Ciao, 

    per fare quello che vuoi dovresti generare la query dinamicamente e poi eseguirla tramite una EXEC.

    Devi aprire un cursore sulla tabella padre e per ogni riga concatenare parti di SQL per arrivare all'istruzione finale. 

    DECLARE @idp VARCHAR(10)
    DECLARE @sqlselect VARCHAR(1000)
    DECLARE @sqlorderby VARCHAR(1000)
    DECLARE @sqlinnerselect VARCHAR(1000)
    
    DECLARE p CURSOR
    FOR
    SELECT intid
    FROM padre
    ORDER BY intid
    
    OPEN p
    
    FETCH NEXT
    FROM p
    INTO @idp
    
    WHILE @@fetch_status = 0
    BEGIN
    	SELECT @sqlselect = COALESCE(@sqlselect + ',', '') + 'tbl' + @idp + '.intid as [' + @idp + ']'
    
    	SELECT @sqlorderby = COALESCE(@sqlorderby + ',', '') + 'tbl' + @idp + '.intid'
    
    	SELECT @sqlinnerselect = COALESCE(@sqlinnerselect + ',', '') + '(select intidpadre, intid from figlio where intidpadre = ' + @idp + ') as tbl' + @idp
    
    	FETCH NEXT
    	FROM p
    	INTO @idp
    END
    
    CLOSE p
    
    DEALLOCATE p
    
    PRINT 'SELECT ' + @sqlselect + ' FROM ' + @sqlinnerselect + ' ORDER BY ' + @sqlorderby
    
    EXEC ('SELECT ' + @sqlselect + ' FROM ' + @sqlinnerselect + ' ORDER BY ' + @sqlorderby)
    


    • Contrassegnato come risposta Carlik mercoledì 4 giugno 2014 13:45
    mercoledì 4 giugno 2014 12:57
  • Risposta spettacolare, a futura memoria , a chi dovesse servire , ho solo aggiunto 
    DECLARE p CURSOR
    FOR
    SELECT DISTINCT Padre.intID
    FROM         Padre INNER JOIN
                          Figlio ON Padre.intID = Figlio.intIDPadre
    ORDER BY Padre.intID
    
    per i padri senza figli

    Carlo

    mercoledì 4 giugno 2014 13:21