1. ホーム
  2. mysql

[解決済み] MySQL "Group By" と "Order By" について

2022-10-12 13:26:53

質問

電子メールのテーブルから多くの行を選択し、差出人別にグループ化することができればと思います。 私のクエリは次のようになります。

SELECT 
    `timestamp`, `fromEmail`, `subject`
FROM `incomingEmails` 
GROUP BY LOWER(`fromEmail`) 
ORDER BY `timestamp` DESC

クエリはほぼ思い通りに動作します - 電子メールでグループ化されたレコードを選択します。問題は、件名とタイムスタンプが、特定の電子メールアドレスの最新のレコードに対応していないことです。

たとえば、それは返すかもしれません。

fromEmail: [email protected], subject: hello
fromEmail: [email protected], subject: welcome

データベース内のレコードがいつ

fromEmail: [email protected], subject: hello
fromEmail: [email protected], subject: programming question
fromEmail: [email protected], subject: welcome

プログラミングの質問」の件名が最も新しい場合、電子メールをグループ化するときに MySQL にそのレコードを選択させるにはどうすればよいですか。

どのように解決するのですか?

簡単な解決策は、クエリを ORDER ステートメントでサブセレクトにまとめることです。 最初 を適用し、GROUP BY を適用します。 :

SELECT * FROM ( 
    SELECT `timestamp`, `fromEmail`, `subject`
    FROM `incomingEmails` 
    ORDER BY `timestamp` DESC
) AS tmp_table GROUP BY LOWER(`fromEmail`)

これはjoinを使うのと似ていますが、見た目はもっときれいです。

GROUP BY句を持つSELECTで非集計カラムを使用することは非標準的です。MySQL は通常、最初に見つかった行の値を返し、残りは破棄します。ORDER BY句は返されたカラムの値のみに適用され、捨てられたカラムには適用されません。

重要な更新 非集計カラムの選択は、以前は実際に動作していましたが、当てにならないでしょう。によると MySQL ドキュメント "これは主に、GROUP BY で名付けられた各非集約カラムのすべての値が、各グループで同じである場合に便利です。サーバは どのような値でも自由に選択することができます。 各グループから自由に値を選ぶことができるので 同じでない限り、選ばれた値は不定である。 ." となります。

現在のところ 5.7.5 ONLY_FULL_GROUP_BYはデフォルトで有効なので、非集計カラムはクエリエラー(ER_WRONG_FIELD_WITH_GROUP)の原因となります。

以下の @mikep が指摘するように、解決策は ANY_VALUE() 5.7 以降では

参照 http://www.cafewebmaster.com/mysql-order-sort-group https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value