Mysql
 sql >> Database >  >> RDS >> Mysql

La query non restituisce risultati solo quando è stato aggiunto ORDER BY

Questo sembra essere un bug in MySQL, riguardo al quale ho segnalato . L'ho ristretto al seguente test case, che ci si aspetterebbe di restituire un singolo record (ma non lo fa):

CREATE TABLE t (x INT NULL);  -- table with nullable column
INSERT INTO  t VALUES (0);    -- but non null data

SELECT   a.x                  -- select our nullable column
FROM     t a, (SELECT NULL) b -- joining it with anything at all

WHERE    EXISTS (             -- but filter on a subquery
           SELECT *
           FROM   (SELECT NULL) c -- doesn't really matter what
           HAVING a.x IS NOT NULL -- provided there is some correlated condition
                                  -- on our nullable column in the HAVING clause
         )

ORDER BY RAND()               -- then perform a filesort on the outer query

Guardalo su sqlfiddle .

Nel tuo caso, puoi fare una serie di cose per risolvere questo problema:

  1. Evita la sottoquery correlata riscrivendo come join:

    SELECT   *
    FROM     people AS p LEFT JOIN (people_stages AS s NATURAL JOIN (
               SELECT   person_id, MAX(created) created
               FROM     people_stages
               GROUP BY person_id
             ) t) ON s.person_id = p.id
    ORDER BY p.last_name
    
  2. Se vuoi mantenere la sottoquery correlata (che generalmente può produrre scarse prestazioni ma è spesso più facile da capire), usa WHERE invece di HAVING :

    SELECT   * 
    FROM     people AS p LEFT JOIN people_stages AS s ON s.person_id = p.id
    WHERE    s.created = (
               SELECT MAX(created)
               FROM   people_stages
               WHERE  person_id = s.person_id
             )
    ORDER BY p.last_name
    
  3. Se non riesci a modificare la query, dovresti scoprire che creando il people_stages.person_id la colonna non nullable risolverà il problema:

    ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
    

    Sembra che avere un indice su quella colonna (che sarebbe necessario per applicare un vincolo di chiave esterna) possa anche aiutare:

    ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
    
  4. In alternativa si potrebbe rimuovere people_stages.person_id dall'elenco di selezione o modificare la strategia del modello dati/indicizzazione/query per evitare un filesort (potrebbe non essere pratico in questo caso, ma li menziono qui per completezza).