Nel corso degli anni ho avuto necessità, diverse volte, di dover fare l’intersezione dei dati di due tabelle di un database.
Poichè penso di non essere l’unico a cui sia utile, voglio spiegare come è possibile fare l’intersezione dei dati di due tabelle con un database MySQL, un database MariaDB, un database PostegreSQL e un database Microsoft SQL, conosciuto come MSSQL.
Oggetto della discussione è, come avete capito, l’intersezione su database relazionali; non è questa la sede per chiedersi se ha senso fare un’intersezione di dati su database NoSQL, quindi non ce lo chiediamo e passiamo oltre.
I dati di cui disponiamo sono due tabelle, chiamate per semplicità t1 e t1b, aventi la stessa struttura, ossia due campi di testo contenenti stringhe.
Le due tabelle contengono lo stesso tipo di dati, ma con alcune differenze nei dati stessi.
Scopo del test è quindi verificare, che tipo di query bisogna costruire, per estrarre i dati che hanno in comune due tabelle, in funzione del motore di database che si utilizza.
Questa la struttura dei dati di esempio.
Tabella t1
nome | cognome |
mario | rossi |
giovanni | verdi |
giuseppe | bianchi |
alessio | gialli |
Tabella t1b
nome | cognome |
mario | rossi |
andrea | verdi |
carlo | bianchi |
alfonso | gialli |
paolo | marroni |
Iniziamo eseguendo il test su Mysql e MariaDB.
La query di intersezione su Mysql
select nome, cognome from t1 where (nome,cognome) IN ( select nome,cognome from t1b );
e questo è il risultato
nome | cognome |
mario | rossi |
Eseguiamo ora il test sugli altri database modificando la query in modo da sfruttare l’operatore INTERSECT, non supportato da MySQL.
Eseguiamo ora il test su PostgreSQL
La query di intersezione su PostgreSQL è la seguente
select nome,cognome from t1 INTERSECT select nome,cognome from t1b;
e questo è il risultato
nome | cognome |
mario | rossi |
Eseguiamo ora il test su MariaDB
La query di intersezione su MariaDB è la seguente
select nome,cognome from t1 INTERSECT select nome,cognome from t1b;
e questo è il risultato
nome | cognome |
mario | rossi |
Eseguiamo ora il test su Microsoft SQL
La query di intersezione su Microsoft SQL è la seguente
select nome,cognome from t1 INTERSECT select nome,cognome from t1b;
e questo è il risultato
nome | cognome |
mario | rossi |
Come avete certamente notato, MSSQL, PostegreSQL e MariaDB si comportano allo stesso modo, consentono di eseguire la stessa query, attraverso l’operatore INTERSECT
Mysql invece ci consente di eseguire l’intersezione attraverso l’esecuzione di una select di select, ossia tramite un annidamento.
Se proviamo ad utilizzare l’operatore INTERSECT con MySQL otteniamo l’errore seguente
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select nome,cognome from t1b' at line 3, Time: 0.001000s
Con tutti i motori citati, possiamo sempre utilizzare la query provata con MySQL, ossia
select nome, cognome from t1 where (nome,cognome) IN ( select nome,cognome from t1b );
Versioni dei motori SQL utilizzati
Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) – 14.0.3048.4 (X64)
psql (PostgreSQL) 11.7 (Ubuntu 11.7-0ubuntu0.19.10.1)
MySQL Ver 8.0.18 for Linux on x86_64 (MySQL Community Server – GPL)
MariaDB 10.3.22-MariaDB-0ubuntu0.19.10.1