sql >> データベース >  >> RDS >> Mysql

ORDER BYが追加された場合にのみ、クエリは結果を返しません

    これはMySQLのバグのようで、レポートを提出しました> 。私はそれを次のテストケースに絞り込みました。このテストケースでは、単一のレコードが返されると予想されます(ただし、返されません)。

    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
    

    sqlfiddle でご覧ください 。

    あなたの場合、これを修正するためにいくつかのことを行うことができます:

    1. 結合として書き直すことにより、相関サブクエリを回避します:

      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. 相関サブクエリ(通常はパフォーマンスが低下する可能性がありますが、多くの場合理解しやすい)を維持する場合は、WHEREを使用します。 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. クエリを変更できない場合は、people_stages.person_idを作成する必要があります。 null許容でない列は問題を回避します:

      ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
      

      その列にインデックスを付けると(外部キー制約を有効にするために必要になる)、次のことも役立つようです。

      ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
      
    4. または、people_stages.person_idを削除することもできます 選択リストから選択するか、データモデル/インデックス作成/クエリ戦略を調整してファイルソートを回避します(この場合は実用的ではないかもしれませんが、完全を期すためにここで言及します)。



    1. Pythondatetime.datetimeオブジェクトをMySQLに挿入する

    2. MySQLがテーブルからすべてのインデックスを削除する

    3. データガードがあるときにフラッシュバックする方法

    4. SwifthttppostデータがMySQLデータベースに挿入されない