6

次のクエリで最初に発生した問題は、group by句が の前に実行されたことorder byです。

saved.recipe_id列は、によって生成された整数です。UNIX_TIMESTAMP()

SELECT
    saved.recipe_id,
    saved.`date`,
    user.user_id
FROM saved
    JOIN user
        ON user.id = saved.user_id
GROUP BY saved.recipe_id
ORDER BY saved.`date` DESC

そこで、サブクエリやその他の bs を使用して、あらゆる種類のさまざまな解決策を試しました。最後に、join節でいくつかの異なるサブクエリを試すことになり、テーブルの順序をfrom節から節に変更する必要がありましたjoin。私は次のことを試してみることにしました:

SELECT
    saved.recipe_id,
    saved.`date`,
    user.user_id
FROM user
    JOIN saved
        ON user.id = saved.user_id
GROUP BY saved.recipe_id
ORDER BY saved.`date` DESC

何らかの理由で、これは正しく順序付けられているように見えますが、なぜですか?
この変更により、クエリを以前よりも正確に並べ替えるにはどうすればよいですか?
本当にそうですか?それとも、たまたま私が反対したテストケースに対してそれを行うのでしょうか?

4

2 に答える 2

12

したがって、次のクエリで最初に発生した問題は、group by 句が order by の前に実行されたことです。

これは問題ではありません。これが、SQL の定義方法と動作方法です。はgroup by、行の新しいセットを作成し、order byそれらの行を並べ替えます。

ここでは順序の問題はありません。「SQLの理解」の問題があります。あなたorder byはクエリの結果を注文しているだけです。これらの結果は によって生成され、group by結合の順序は結果とは関係ありません。

Hidden Columns と呼ばれる MySQL 拡張機能を使用しています。これは、集計関数 (など) の一部ではない、または の一部ではないselect(またはhavingまたは句)内の列を含む集計クエリがある場合です。ドキュメントからの引用は次のとおりです。order bysum()group by

MySQL は GROUP BY の使用を拡張して、選択リストが GROUP BY 句で指定されていない非集計列を参照できるようにします。これは、前述のクエリが MySQL で有効であることを意味します。この機能を使用すると、不要な列の並べ替えやグループ化を回避してパフォーマンスを向上させることができます。ただし、これは主に、GROUP BY で指定されていない各非集計列のすべての値が各グループで同じである場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、それらが同じでない限り、選択された値は不確定です。さらに、各グループからの値の選択は、ORDER BY 句を追加しても影響を受けません。結果セットのソートは値が選択された後に行われ、ORDER BY はサーバーが選択する各グループ内の値には影響しません。

おそらく、最新の日付とそれに関連付けられたユーザーが必要です。次のクエリは、必要なことを正しく一貫して実行します。

SELECT saved.recipe_id, max(saved.`date`) as MostRecentDate,
       substring_index(group_concat(user.user_id), ',', 1) as MostRecentUser
FROM user JOIN
     saved
     ON user.id = saved.user_id
GROUP BY saved.recipe_id
ORDER BY max(saved.`date`) DESC;
于 2013-09-12T12:04:57.040 に答える