Alcuni problemi con MySQL si ripresentano identici a distanza di anni e progetti diversi, tanto da meritare una nota rapida da tenere a portata di mano invece di doverli risolvere da capo ogni volta. Eccone tre tra i più comuni lavorando su un'installazione WAMP.
MySQL che rifiuta query GROUP BY "non standard"
A partire da MySQL 5.7, la modalità ONLY_FULL_GROUP_BY è attiva di default e rifiuta le query GROUP BY che selezionano colonne non presenti nel raggruppamento né racchiuse in una funzione di aggregazione — una query che su versioni precedenti funzionava silenziosamente. La correzione corretta è riscrivere la query in modo conforme allo standard SQL; una disattivazione temporanea, utile solo per capire se il problema è davvero questo, si fa così:
-- SOLO per diagnosi: disattiva ONLY_FULL_GROUP_BY per la sessione corrente
SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
Va usata come strumento diagnostico, non come correzione definitiva: lasciare disattivato questo controllo in produzione nasconde query ambigue che possono restituire righe arbitrarie tra quelle del gruppo.
Nomi di tabella case-sensitive su Windows
Su Windows, MySQL tratta i nomi delle tabelle in modo case-insensitive di default, mentre su Linux sono case-sensitive: un progetto sviluppato in locale su WAMP può quindi funzionare anche con un mix di maiuscole/minuscole incoerente nel codice, e rompersi silenziosamente una volta spostato su un server Linux in produzione. Per allineare il comportamento locale a quello (più severo) di produzione, in my.ini:
; Nella sezione [mysqld] di my.ini (es. C:\wamp64\bin\mysql\mysqlX.X.X\my.ini)
[mysqld]
lower_case_table_names = 2
Il valore 2 conserva la scrittura originale del nome tabella ma lo confronta in modo case-insensitive: un compromesso comodo in sviluppo, da verificare comunque contro la configurazione reale del server di produzione, che potrebbe usare 1 o 0. La modifica richiede un riavvio del servizio MySQL.
Trovare i duplicati con GROUP BY e HAVING
Un classico che vale la pena ricordare a memoria: individuare i valori duplicati di una colonna non richiede una subquery complessa, basta raggruppare e filtrare sul conteggio con HAVING.
-- Trova i valori di 'codice' che compaiono più di una volta nella tabella
SELECT codice, COUNT(*) AS occorrenze
FROM articoli
GROUP BY codice
HAVING COUNT(*) > 1;
Da qui, per arrivare agli id delle righe duplicate (non solo al valore che si ripete), basta una join della tabella con se stessa sul risultato di questa query, oppure una subquery IN se il volume di dati resta contenuto.