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

Forespørgsel returnerer kun ingen resultater, når ORDER BY tilføjet

Dette ser ud til at være en fejl i MySQL, som jeg har indgivet en rapport om . Jeg har indsnævret det til følgende testcase, som man ville forvente at returnere en enkelt post (men det gør den ikke):

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

Se den på sqlfiddle .

I dit tilfælde kan du gøre en række ting for at løse dette:

  1. Undgå den korrelerede underforespørgsel ved at omskrive som en joinforbindelse:

    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. Hvis du vil beholde den korrelerede underforespørgsel (som generelt kan give dårlig ydeevne, men ofte er nemmere at forstå), skal du bruge WHERE i stedet for 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. Hvis du ikke er i stand til at ændre forespørgslen, bør du opdage, at gøre people_stages.person_id kolonne non-nullable vil komme uden om problemet:

    ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
    

    Det ser ud til, at det at have et indeks på den kolonne (som ville være påkrævet for at påvirke en fremmednøglebegrænsning) også kan hjælpe:

    ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
    
  4. Alternativt kunne man fjerne people_stages.person_id fra udvalgslisten, eller juster datamodellen/indekseringen/forespørgselsstrategien for at undgå en filsortering (måske ikke være praktisk i dette tilfælde, men jeg nævner dem her for fuldstændighedens skyld).



  1. Hvordan får man data fra en mysql-database ved hjælp af javascript?

  2. MySQL-forespørgsel for at modtage tilfældige kombinationer fra to tabeller

  3. Sådan sletter du dublerede rækker uden entydig identifikator

  4. MySQL og SQLite forskelle i SQL