Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Seleziona nuovamente un elenco delimitato da virgole raggruppato da un ID

select ET1.EntryID,
       (
       select ', '+T.Name
       from Tags as T
         inner join EntryTag as ET2
           on T.TagID = ET2.TagID
       where ET1.EntryID = ET2.EntryID
       for xml path(''), type
       ).value('substring(text()[1], 3)', 'varchar(max)') as TagsCommaDelimited
from EntryTag as ET1
group by ET1.EntryID

Analisi della query

La query principale esegue un group by quindi ottieni solo una riga per ogni EntryID .

La colonna TagsCommaDelimited viene creato con una sottoquery correlata.

In SQL Server for xml path viene utilizzato per creare una rappresentazione XML del risultato di una query. Hai un buon controllo su come viene creato l'XML usando gli alias di colonna e i parametri per path e root .

Il valore concatenato ', '+T.Name nella sottoquery correlata non avrà un nome di colonna e il parametro vuoto su for xml path('') crea l'xml senza alcun tag. Verrà restituito un solo valore di testo.

Quando aggiungi type a un for xml query il tipo di dati sarà XML .

Per ottenere un valore da un XML è necessario utilizzare il value() metodo. Potresti eseguire il cast su una stringa, ma se lo facessi otterresti ad esempio & nella stringa in cui hai usato & .

Il primo parametro in value() function è l'espressione xQuery utilizzata per ottenere il valore desiderato. Usa text() per specificare che si desidera solo il valore per l'elemento corrente. [1] sta dicendo a SQL Server che vuoi trovare il primo nodo di testo (ne hai solo uno qui) ma è ancora necessario.

La stringa creata da for xml la query ha una virgola in più e uno spazio all'inizio della stringa e deve essere rimossa. Qui utilizzo la funzione XQuery substring per ottenere tutto tranne i primi due caratteri.

Il secondo parametro per value() specifica il tipo di dati che deve essere restituito.