ソリューションでは、一部のフィールド(この場合は)でグループ化することを許可するGROUP BY句の拡張を利用していますpost_author。
GROUP BY wp_posts.post_author
集計されていない列を選択します。
SELECT wp_posts.*
group by句にリストされていないもの、または集約関数(MIN、MAX、COUNTなど)で使用されていないもの。
GROUP BY句の拡張の正しい使用
これは、非集計列のすべての値がすべての行で等しい場合に役立ちます。
たとえば、テーブルGardensFlowers(name庭でflower育つ庭のテーブル)があるとします。
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
そして、複数の花が育つ庭で育つすべての花を抽出したいとします。次に、サブクエリを使用する必要があります。たとえば、次のように使用できます。
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
代わりにガーダー内で唯一の花であるすべての花を抽出する必要がある場合は、HAVING条件をに変更するだけで済みますがHAVING COUNT(DISTINCT flower)=1、MySqlではこれを使用することもできます。
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
サブクエリはなく、標準SQLではありませんが、より単純です。
GROUP BY句の拡張の誤った使用
しかし、すべての行で等しくない非集計列を選択するとどうなりますか?MySqlがその列に選択する値はどれですか?
MySqlは常に最初に遭遇した値を選択するようです。
遭遇する最初の値が正確に希望する値であることを確認するGROUP BYには、順序付けされたクエリにを適用する必要があるため、サブクエリを使用する必要があります。それ以外の場合はできません。
MySqlは常に最初に遭遇する最初の行を選択するという前提で、GROUP BYの前に行を正しくソートしています。しかし残念ながら、ドキュメントを注意深く読むと、この仮定が正しくないことに気付くでしょう。
常に同じではない非集計列を選択する場合、MySqlは任意の値を自由に選択できるため、実際に表示される結果の値は不確定です。
非集計列の最初の値を取得するためのこのトリックが頻繁に使用されていることがわかり、通常/ほとんど常に機能しますが、(自分のリスクで)ときどき使用します。しかし、それは文書化されていないため、この動作に依存することはできません。
このリンク(ypercubeに感謝!)GROUP BYトリックは最適化されていますが、おそらく最適化エンジンが異なるため、同じクエリがMySqlとMariaDBの間で異なる結果を返す状況を示しています。
したがって、このトリックが機能する場合、それは運の問題です。
他の質問への受け入れ答えは 私には間違っているになります。
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_dateは非集計列であり、その値は公式には未定ですが、最初にpost_date遭遇する可能性があります。ただし、GROUP BYトリックは順序付けられていないテーブルに適用されるため、どちらが最初にpost_date発生するかはわかりません。
おそらく、単一の著者の唯一の投稿である投稿を返しますが、これは必ずしも確実ではありません。
可能な解決策
これは可能な解決策になると思います:
SELECT wp_posts.*
FROM wp_posts
WHERE id IN (
SELECT max(id)
FROM wp_posts
WHERE (post_author, post_date) = (
SELECT post_author, max(post_date)
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
) AND wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
)
内部クエリでは、すべての著者の最大投稿日を返しています。次に、同じ作者が理論的に同時に2つの投稿を持つことができるという事実を考慮に入れているので、最大IDのみを取得しています。そして、それらの最大IDを持つすべての行を返します。IN句の代わりに結合を使用すると、より高速にできます。
(それIDが増加しているだけであることが確かで、それがをID1 > ID2意味しているpost_date1 > post_date2場合は、クエリをはるかに簡単にすることができますが、これが当てはまるかどうかはわかりません)。
post_authorでpost_dateはないため、一意の行を取得するにはさらに多くのものが必要ですpost_author