1. ホーム
  2. マイスル

[解決済み] MySQL order by before group by

2022-04-02 02:14:17

質問

似たような質問がたくさんありますが、どの質問にも適切に答えているとは思えません。

現在最も人気のあるものから続けます。 質問 ということで、彼らの例を使ってみましょう。

この例でのタスクは、データベース内の各著者の最新の投稿を取得することです。

このクエリの例では、常に最新の投稿が返されるとは限らないので、使い物にならない結果が返されます。

SELECT wp_posts.* FROM wp_posts
    WHERE wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
    GROUP BY wp_posts.post_author           
    ORDER BY wp_posts.post_date DESC

現在受け入れられている回答は

SELECT
    wp_posts.*
FROM wp_posts
WHERE
    wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
HAVING wp_posts.post_date = MAX(wp_posts.post_date) <- ONLY THE LAST POST FOR EACH AUTHOR
ORDER BY wp_posts.post_date DESC

残念ながら、この回答は単純明快な間違いであり、多くの場合、元のクエリよりも安定した結果を得ることができません。

私の最良の解決策は、次のような形式のサブクエリを使用することです。

SELECT wp_posts.* FROM 
(
    SELECT * 
    FROM wp_posts
    ORDER BY wp_posts.post_date DESC
) AS wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author 

では、私の質問は簡単なものです。 サブクエリに頼らずにグループ化する前に行を並べ替える方法はありますか?

編集 : この質問は別の質問からの続きで、私の状況とは若干仕様が異なります。その特定の投稿の一意な識別子であるwp_posts.idも存在すると仮定してよい(はず)です。

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

を使用することで ORDER BY をサブクエリで使用することは、この問題の最良の解決策ではありません。

を取得するための最良の解決策は max(post_date) サブクエリを使用して最大日付を返し、それをテーブルに結合して post_author と最大値の日付が表示されます。

という解答になるはずです。

SELECT p1.* 
FROM wp_posts p1
INNER JOIN
(
    SELECT max(post_date) MaxPostDate, post_author
    FROM wp_posts
    WHERE post_status='publish'
       AND post_type='post'
    GROUP BY post_author
) p2
  ON p1.post_author = p2.post_author
  AND p1.post_date = p2.MaxPostDate
WHERE p1.post_status='publish'
  AND p1.post_type='post'
order by p1.post_date desc

以下のようなサンプルデータがある場合。

CREATE TABLE wp_posts
    (`id` int, `title` varchar(6), `post_date` datetime, `post_author` varchar(3))
;

INSERT INTO wp_posts
    (`id`, `title`, `post_date`, `post_author`)
VALUES
    (1, 'Title1', '2013-01-01 00:00:00', 'Jim'),
    (2, 'Title2', '2013-02-01 00:00:00', 'Jim')
;

サブクエリは、最大日付と著者を返そうとしています。

MaxPostDate | Author
2/1/2013    | Jim

そして、それをテーブルに結合しているので、両方の値に対して、その投稿の完全な詳細を返すことになります。

参照 SQL Fiddle with Demo .

このデータを正確に返すためにサブクエリを使用するという私のコメントを発展させるために。

MySQLは GROUP BY に含むすべてのカラムを SELECT のリストを作成します。 その結果、もしあなたが GROUP BY に属する他のカラムの値が、10個のカラムを返すという保証はない。 post_author が返されます。 もしそのカラムが GROUP BY MySQLはどのような値を返すべきかを選択します。

サブクエリと集約関数を使用することで、毎回正しい著者と投稿が返されることが保証されます。

余談ですが、MySQL では ORDER BY をサブクエリに適用することができます。 GROUP BY のすべてのカラムに適用されるわけではありません。 SELECT この動作は、SQL Serverを含む他のデータベースでは認められていません。