Sql Server 2012 - merge di campi separati da virgola (o trattino)

di il
3 risposte

Sql Server 2012 - merge di campi separati da virgola (o trattino)

Salve a tutti, intanto mi presento: mi chiamo Flavio, lavoro nel settore della telefonia e non capisco un accidente di SQL Server (ho competenze proprio basilari in merito). Magari per voi è banale, ma io sto realmente impazzendo.
Ho fatto questa query:
SELECT ALL
  RTrim(ARTICO.CODICE) AS [Cod.Ricambio],
 RTrim(ARTCLA4.CODICE) AS [Modello Princ.],
 RTrim(ARTICO1.CODICE) AS [Cod.Compatib.]
FROM
  ARTICO
  LEFT JOIN ARTSOS ON ARTSOS.IDARTICO = ARTICO.ID
  LEFT JOIN ARTICO ARTICO1 ON ARTSOS.IDARTSOS = ARTICO1.ID
  LEFT JOIN ARTCLA4 ON ARTCLA4.ID = ARTICO.IDARTCLA4
WHERE
  ARTICO.IDLINEEP = 4
------------------------------

Cod. Ricambio ha dei doppioni, perché Cod. Compatib. può avere più valori (sono delle compatibilità di ricambi di smartphone). Io avrei bisogno che questo cod. compatib. venga accorpato (mentre modello princ rimane sempre uguale e segue diciamo il codice del ricambio) ed unito con un qualsiasi separatore.

Ad esempio potrebbe essere così
codice001 modello001 modello001
codice001 modello001 modello002
codice001 modello001 modello003

io vorrei come risultato
codice001 modello001 modello001-modello002-modello003

Mi potete aiutare per cortesia? Grazie in anticipo, ho letto il regolarmento e credo di averlo rispettato, mi scuso in anticipo se così non fosse

Grazie ancora!

3 Risposte

  • Re: Sql Server 2012 - merge di campi separati da virgola (o trattino)

    Salve,
    la concatenazione di "stringhe" puo' essere effettuata utilizzando l'espressione FOR XML PATH, vedi https://sqlandme.com/2011/04/27/tsql-concatenate-rows-using-for-xml-path/
    nell'esempio, viene utilizzata una sub query per ogni riga restituita dalla query principale su Production.ProductCategory... si puo' ovviamente suddividere la query eseguendo una common table expression da mettere poi in JOIN con la query principale...
    trivialmente,
    
    PRINT 'esplosione di JOIN completa...';
    SELECT a.CODICE AS [Cod.Ricambio]
    	, a4.CODICE AS [Mod.Principale]
    	FROM dbo.ARTICLA4 a4
    		JOIN dbo.ARTICO a ON a.IDARTCLA4 = a4.Id
    	WHERE 1 = 1-- il tuo filtro;
    		
    PRINT 'tradotto in sub-query in linea..';
    SELECT 	a.CODICE AS [Cod.Ricambio],
    		STUFF((SELECT '-' + a4.CODICE AS [text()]
    					FROM dbo.ARTICLA4 a4
    					WHERE a4.Id = a.Id
    					FOR XML PATH('') 
    			), 1, 1, '' )  AS [Mod.Principale]
    	FROM dbo.ARTICO a
    	WHERE 1 = 1-- il tuo filtro;
    
    PRINT 'tradotto in common table expression da mettere poi in JOIN..';
    WITH cteRicambi AS (
    	SELECT a.Id,
    		STUFF((SELECT '-' + a4.CODICE AS [text()]
    					FROM dbo.ARTICLA4 a4
    					WHERE a4.Id = a.Id
    					FOR XML PATH('') 
    			), 1, 1, '' )  AS [Mod.Principale]
    	FROM dbo.ARTICO a
    	)
    	SELECT a.CODICE AS [Cod.Ricambio]
    		, r.[Mod.Principale]
    		FROM dbo.ARTICO a
    			LEFT JOIN cteRicambi r ON r.[Id] = a.[Id]
    	WHERE 1 = 1-- il tuo filtro;
    --<-------
    esplosione di JOIN completa...
    Cod.Ricambio Mod.Principale
    ------------ --------------
    art1         mod1
    art2         mod1
    art3         mod1
    art2         mod2
    art3         mod2
    
    tradotto in sub-query in linea..
    Cod.Ricambio Mod.Principale
    ------------ --------------
    art1         mod1
    art2         mod1-mod2
    art3         mod1-mod2
    art.4        NULL
    
    tradotto in common table expression da mettere poi in JOIN..
    Cod.Ricambio Mod.Principale
    ------------ --------------
    art1         mod1
    art2         mod1-mod2
    art3         mod1-mod2
    art.4        NULL
    
    le common table expression, al di la' del fatto che i piani di escuzione, i risultati e le performace siano identici rispetto alle sub query inline, sono solitamente piu' "accattivanti" da usare in quanto "visivamente" sono piu' leggibili...

    giusto per informazione, sarebbe (almeno per la mia esperieza) indicato postare anche un mini scenario composto dal DDL (CREATE TABLE) e istruzioni INSERT INTO minimali al fine di far si che chi voglia aiutare non debba rigenerare l'intero scenario anche con l'ovvio rischio di sbagliare nelle intenzioni...

    invece, riguardo al tua query, personalmente ti consiglio di referenziare gli oggetti coinvolti sempre in maniera completa, quindi indicandoli sempre come [schema_name].[object_name], diversamente i processori della query di SQL Server saranno sempre costretti a generare un nuovo piano di esecuzione ad ogni chiamata, senza poter quindi riutilizzare quelli gia' nella cache, con dispendio inuntile di risorse...
    saluti omnia
    --
    Andrea
  • Re: Sql Server 2012 - merge di campi separati da virgola (o trattino)

    Grazie mille, provo subito! Grazie anche dei suggerimenti, purtroppo sono abbastanza a digiuno in materia per cui sono dettagli che non sono in grado di considerare (mi occupo di hardware, non di software). Un collaboratore dell'azienda dove lavoro mi aveva mandato questa soluzione, che funziona ma ho notato che mi lascia la virgola in fondo
    SELECT DISTINCT 
        RTrim(ARTICO.CODICE) AS [Cod.Ricambio],
        RTrim(ARTICO.DESCR) AS Descrizione,
        RTrim(ARTCLA4.CODICE) AS [Modello Princ.],
        (
    SELECT  RTrim(ARTICO1.CODICE) + ','  AS 'data()' 
    FROM
        ARTICO A
    LEFT JOIN 
        ARTSOS ON ARTSOS.IDARTICO = ARTICO.ID
    LEFT JOIN 
        ARTICO ARTICO1 ON ARTSOS.IDARTSOS = ARTICO1.ID
    LEFT JOIN 
        ARTCLA4 ON ARTCLA4.ID = ARTICO.IDARTCLA4
    WHERE
        ARTICO.IDLINEEP = 4 AND A.CODICE = ARTICO.CODICE 
     FOR XML PATH('') 
    ) AS [Cod.Compatib.]
    FROM
        ARTICO
    LEFT JOIN 
        ARTSOS ON ARTSOS.IDARTICO = ARTICO.ID
    LEFT JOIN 
        ARTICO ARTICO1 ON ARTSOS.IDARTSOS = ARTICO1.ID
    LEFT JOIN 
        ARTCLA4 ON ARTCLA4.ID = ARTICO.IDARTCLA4
    WHERE
        ARTICO.IDLINEEP = 4
    
    Grazie ancora, gentilissimo!
  • Re: Sql Server 2012 - merge di campi separati da virgola (o trattino)

    Sfortunatamente non funziona

    Funziona la query fatta dal mio amico ma c'è la rottura di scatole della virgola finale. Mi sa che ci rinuncio!
Devi accedere o registrarti per scrivere nel forum
3 risposte