MySQL
Gestione di dati sparsi o mancanti
Ricerca…
Lavorare con le colonne che contengono valori NULL
In MySQL e in altri dialetti SQL, i valori NULL
hanno proprietà speciali.
Considera la seguente tabella contenente i candidati al lavoro, le società per le quali hanno lavorato e la data in cui hanno lasciato la società. NULL
indica che un richiedente lavora ancora presso l'azienda:
CREATE TABLE example
(`applicant_id` INT, `company_name` VARCHAR(255), `end_date` DATE);
+--------------+-----------------+------------+
| applicant_id | company_name | end_date |
+--------------+-----------------+------------+
| 1 | Google | NULL |
| 1 | Initech | 2013-01-31 |
| 2 | Woodworking.com | 2016-08-25 |
| 2 | NY Times | 2013-11-10 |
| 3 | NFL.com | 2014-04-13 |
+--------------+-----------------+------------+
Il tuo compito è quello di comporre una query che restituisce tutte le righe dopo il 2016-01-01
, compresi i dipendenti che lavorano ancora in un'azienda (quelli con date di fine NULL
). Questa affermazione selezionata:
SELECT * FROM example WHERE end_date > '2016-01-01';
non riesce a includere alcuna riga con valori NULL
:
+--------------+-----------------+------------+
| applicant_id | company_name | end_date |
+--------------+-----------------+------------+
| 2 | Woodworking.com | 2016-08-25 |
+--------------+-----------------+------------+
Secondo la documentazione MySQL , i confronti usando gli operatori aritmetici <,>, = e <> restituiscono NULL
invece di un valore booleano TRUE
o FALSE
. Pertanto una riga con un end_date NULL
non è né maggiore del 2016-01-01 né inferiore al 2016-01-01.
Questo può essere risolto utilizzando le parole chiave IS NULL:
SELECT * FROM example WHERE end_date > '2016-01-01' OR end_date IS NULL;
+--------------+-----------------+------------+
| applicant_id | company_name | end_date |
+--------------+-----------------+------------+
| 1 | Google | NULL |
| 2 | Woodworking.com | 2016-08-25 |
+--------------+-----------------+------------+
Lavorare con NULL diventa più complesso quando l'attività coinvolge funzioni di aggregazione come MAX()
e una clausola GROUP BY
. Se la tua attività dovesse selezionare la data di assunzione più recente per ciascun candidato id, la seguente query sembrerebbe un primo tentativo logico:
SELECT applicant_id, MAX(end_date) FROM example GROUP BY applicant_id;
+--------------+---------------+
| applicant_id | MAX(end_date) |
+--------------+---------------+
| 1 | 2013-01-31 |
| 2 | 2016-08-25 |
| 3 | 2014-04-13 |
+--------------+---------------+
Tuttavia, sapendo che NULL
indica che un candidato è ancora impiegato in un'azienda, la prima riga del risultato è imprecisa. L'utilizzo di CASE WHEN
fornisce una soluzione alternativa per il problema NULL
:
SELECT
applicant_id,
CASE WHEN MAX(end_date is null) = 1 THEN 'present' ELSE MAX(end_date) END
max_date
FROM example
GROUP BY applicant_id;
+--------------+------------+
| applicant_id | max_date |
+--------------+------------+
| 1 | present |
| 2 | 2016-08-25 |
| 3 | 2014-04-13 |
+--------------+------------+
Questo risultato può essere ricollocato nella tabella di example
originale per determinare l'azienda a cui ha lavorato per ultimo un richiedente:
SELECT
data.applicant_id,
data.company_name,
data.max_date
FROM (
SELECT
*,
CASE WHEN end_date is null THEN 'present' ELSE end_date END max_date
FROM example
) data
INNER JOIN (
SELECT
applicant_id,
CASE WHEN MAX(end_date is null) = 1 THEN 'present' ELSE MAX(end_date) END max_date
FROM
example
GROUP BY applicant_id
) j
ON data.applicant_id = j.applicant_id AND data.max_date = j.max_date;
+--------------+-----------------+------------+
| applicant_id | company_name | max_date |
+--------------+-----------------+------------+
| 1 | Google | present |
| 2 | Woodworking.com | 2016-08-25 |
| 3 | NFL.com | 2014-04-13 |
+--------------+-----------------+------------+
Questi sono solo alcuni esempi di come lavorare con valori NULL
in MySQL.