In questo articolo parleremo di tre nuove e utilissime funzioni disponibili nelle versioni 2017 e 2019 di Microsoft Sql Server rendendo ancora più semplice e immediata l’esperienza di sviluppo dei programmatori T-SQL.
Funzione TRIM
Fino alla versione 2016 di Sql Server, per eliminare gli spazi bianchi a sinistra e a destra di una stringa, occorreva combinare le due funzione LTRIM e RTRIM come nell’esempio in basso:
SELECT LTRIM(RTRIM(‘ string ‘ ))
Questa sintassi risulta spesso “pesante”, soprattutto in quei contesti dove tale funzione è piuttosto frequente, pensiamo ad esempio alle fasi di data quality e integration.
Finalmente, possiamo raggiungere il medesimo risultato con la sola funzione TRIM, analogamente a quanto già possibile su altri DBMS come ad esempio su Oracle.
SELECT TRIM(‘ string ‘ )
Oltre agli spazi bianchi, la funzione TRIM può essere utilizzata per eliminare anche dei caratteri particolari. Questo permette di risolvere agevolmente problematiche molto comuni come “eliminare gli zeri a sinistra della stringa” che, ad esempio, emergono spesso da colonne che contengono indistintamente codici fiscali e partite iva. Vediamo uno script d’esempio
CREATE TABLE #test (codice varchar(10))
INSERT INTO #test VALUES (’01’),(’02’),(‘2’),(‘0’),(‘001’)
SELECT Codice,
trim(‘0’ from codice) as AfterTrim
FROM #test
Codice | AfterTrim |
01 | 1 |
02 | 2 |
2 | 2 |
0 | |
001 | 1 |
Funzione CONCAT_WS
Molto spesso si ha l’esigenza di concatenare più colonne separandole con una virgola oppure un altro separatore.
Creiamo un semplice caso d’esempio
CREATE TABLE #test2 (nome varchar(50),
cognome varchar(50),
citta varchar(50),
indirizzo varchar(50))
INSERT INTO #test2 values (‘nicola’,’iantomasi’,’torino’,null), (‘giovanni’,’rossi’,’milano’,’via montenapoleone’)
Per concatenare le quattro colonne dell’esempio, occorre ripetere il carattere separatore tre volte.
SELECT CONCAT(nome,’,’,cognome,’,’,citta,’,’,indirizzo) as AfterConcat
FROM #test2
Se dovessimo concatenare dieci colonne, occorrerebbe ripeterlo nove volte…
Tramite la funzione CONCAT_WS possiamo invece indicare il carattere separatore una sola volta, in questo modo
SELECT CONCAT_WS(‘,’,nome,cognome,citta,indirizzo) as AfterConcatWs
FROM #test2
Molto importante è notare il diverso comportamento delle funzioni CONCAT e CONCAT_WS in presenza di null.
La funzione ConcatWS elimina il separatore nel caso in cui la colonna seguente contenga un null. Occorre essere consapevoli di questo comportamento: probabilmente questo non è il comportamento che vogliamo se ad esempio il nostro obiettivo è convertire in formato csv i dati della tabella.
Tuttavia possiamo “porre rimedio” inglobando le colonne all’interno della funzione isnull
SELECT CONCAT_WS(‘,’, isnull(nome,”),isnull(cognome,”),isnull(citta,”),isnull(indirizzo”)) as AfterConcatWs
from #test2
Al contrario, se volessimo creare una stringa indirizzo con esattamente questa caratteristica di “saltare” le colonne, l’implementazione con la funzione CONCAT risulterebbe molto più lunga e frustante.
Funzione STRING_AGG
In presenza di una clausola group by, spesso si ha la necessità di concatenare (eventualmente con un separatore) i valori di una colonna di tipo varchar relativi alla chiave di aggregazione.
Prima del 2017, per risolvere questo problema gli sviluppatori T-SQL hanno dato sfoggio della loro abilità e creatività utilizzando le più svariate tecniche: funzioni xml path, conversioni in json, variabili che si concatenano con esse stesse, eccetera…
Da SQL Server 2017 abbiamo a disposizione una nuova funzione di aggrezione utilissima: STRING_AGG.
Niente può essere più esplicativo di uno script d’esempio
CREATE TABLE #test3 (IdConto int, IdCliente int)
INSERT INTO #test3 VALUES (1,1),(1,2),(2,3),(3,4),(3,null)
SELECT IdConto,
string_agg(IdCliente,’;’) as ClientiCointestatari
FROM #test3
GROUP BY IdConto
IdCconto | ClientiCointestatari |
1 | 1;2 |
2 | 3 |
3 | 4 |
Notiamo inoltre la conversione implicita di colonne int in varchar e il comportamento in presenza di null.
Esercizio sulle funzioni STRING_AGG e CONCAT_WS
Combinando le due funzioni STRING_AGG e CONCAT_WS possiamo convertire facilmente una tabella relazionale nel contenuto di un file csv.
SELECT STRING_AGG( CONCAT_WS( ‘;’, isnull(Nome,”), isnull(Cognome,”), char(13)) ) As CsvRow
FROM CLIENTI
Bonus: Funzione APPROX_COUNT_DISTINCT
Nel caso di elevate quantità di dati, l’utilizzo di una COUNT(DISTINCT ) potrebbe essere deleterio in termini di performance.
APPROX_COUNT_DISTINCT fornisce un valore approssimato rispetto al COUNT(DISTINCT) con delle performance migliori. Per la precisione
al 97% l”errore sarà inferiore del 2%
SELECT IdFatture,
APPROX_COUNT_DISTINCT(IdCliente) AS NumeroApprossimatoDiClienti
FROM Fatture
GROUP BY IdFatture
Tuttavia, occorre comunque fare massima attenzione alle performance come sottolineato da Pinal Dave in questo interessante articolo.
Nuove funzioni SQL Server 2017 e 2019: e adesso?
Se vuoi padroneggiare tutti i costrutti avanzati del linguaggio T-SQL come le window function, il cross apply e l’outer apply o le clausole Grouping sets visita la pagina del nostro corso sul linguaggio T-SQL.