MySQL の order by の前に group by を実行する 質問する

MySQL の order by の前に group by を実行する 質問する

ここには同様の質問がたくさんありますが、どれも質問に適切に答えていないと思います。

現在最も人気のあるものから続けます質問よろしければ、彼らの例を使ってください。

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

この例のクエリでは、必ずしも最新の投稿が返されるわけではないため、使用できない結果が生成されます。

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 もあると想定できます (想定する必要があります)。

ベストアンサー1

サブクエリで を使用することは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フィドル

サブクエリを使用してこのデータを正確に返すことに関する私のコメントを拡張します。

GROUP BYMySQL では、リストに含めるすべての列を強制するわけではありませんSELECT。そのため、GROUP BY1 つの列のみを指定して合計 10 列を返す場合、返される列に属する他の列の値が保証されませんpost_author。列がリストに含まれていない場合、GROUP BYMySQL は返される値を選択します。

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

ちなみに、MySQL ではORDER BYサブクエリで を使用でき、リストGROUP BY内のすべての列に を適用することはできませんがSELECT、この動作は SQL Server を含む他のデータベースでは許可されていません。

おすすめ記事