Çözümünüz, bazı alanlara göre gruplandırmaya izin veren GROUP BY deyimine yönelik bir uzantı kullanıyor (bu durumda, sadece post_author
):
GROUP BY wp_posts.post_author
ve birleştirilmemiş sütunları seçin:
SELECT wp_posts.*
grupta yan tümce olarak listelenmeyen veya toplama işlevinde kullanılmayan (MIN, MAX, COUNT, vb.).
Uzantıyı GROUP BY deyimine doğru kullanma
Bu, toplanmamış sütunların tüm değerleri her satır için eşit olduğunda kullanışlıdır.
Örneğin, bir bahçeniz olduğunu varsayalım GardensFlowers
( name
bahçede flower
büyüyen bahçede):
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
ve birden fazla çiçeğin yetiştiği bir bahçede yetişen tüm çiçekleri çıkarmak istiyorsunuz. Sonra bir alt sorgu kullanmak zorundasınız, örneğin bunu kullanabilirsiniz:
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
Bunun yerine bahçedeki tek çiçek olan tüm çiçekleri çıkarmanız gerekiyorsa, HAVING koşulunu sadece değiştirebilirsiniz HAVING COUNT(DISTINCT flower)=1
, ancak MySql de bunu kullanmanıza izin verir:
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
alt sorgu yok, standart SQL değil, daha basit.
GROUP BY yantümcesine yanlış uzantı kullanımı
Ancak, her satır için eşit olmayan birleştirilmiş sütunları SEÇERSENİZ ne olur? MySql'in bu sütun için seçtiği değer nedir?
Görünüşe göre MySql her zaman karşılaştığı İLK değeri seçer .
Karşılaştığı ilk değerin tam olarak istediğiniz değer olduğundan emin olmak için, GROUP BY
sıralı bir sorguya a uygulamanız gerekir , dolayısıyla bir alt sorgu kullanmanız gerekir. Aksi halde yapamazsın.
MySql'in her zaman karşılaştığı ilk satırı seçtiği varsayımı göz önüne alındığında, satırları GROUP BY'dan önce doğru bir şekilde sıralıyorsunuz. Ancak ne yazık ki, belgeleri dikkatlice okursanız, bu varsayımın doğru olmadığını fark edeceksiniz.
Her zaman aynı olmayan birleştirilmiş sütunları seçerken, MySql herhangi bir değer seçmekte serbesttir, bu nedenle gerçekte gösterdiği sonuç belirsizdir .
Toplanmayan bir sütunun ilk değerini elde etmek için bu hile çok kullanılır ve genellikle / neredeyse her zaman çalışır, bazen de (kendi riskimde) kullanıyorum. Ancak belgelenmediği için bu davranışa güvenemezsiniz.
Bu bağlantı (teşekkürler ypercube!) GROUP BY hilesi optimize edildi , aynı sorgunun muhtemelen farklı bir optimizasyon motoru nedeniyle MySql ve MariaDB arasında farklı sonuçlar döndürdüğü bir durumu gösteriyor.
Yani, bu hile işe yararsa, bu sadece bir şans meselesidir.
Diğer soru üzerine kabul cevabı bana yanlış görünüyor:
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_date
birleştirilmiş olmayan bir sütundur ve değeri resmi olarak belirsizdir, ancak büyük olasılıkla ilk post_date
karşılaşılan değer olacaktır . Ancak GROUP BY hilesi sırasız bir tabloya uygulandığından, ilk post_date
karşılaşılanın hangisi olduğundan emin değil .
Muhtemelen tek bir yazarın tek mesajları olan yayınları döndürür, ancak bu bile her zaman kesin değildir.
Olası bir çözüm
Bunun olası bir çözüm olabileceğini düşünüyorum:
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
)
İç sorguda her yazar için maksimum gönderi tarihini döndürüyorum. Daha sonra aynı yazarın teorik olarak aynı anda iki gönderi olabileceğini göz önünde bulunduruyorum, bu yüzden sadece maksimum kimliği alıyorum. Ve sonra bu maksimum kimliğe sahip tüm satırları döndürüyorum. IN yan tümcesi yerine birleşimler kullanılarak daha hızlı yapılabilir.
(Bunun ID
yalnızca arttığından eminseniz ve bunun ID1 > ID2
da anlamı varsa post_date1 > post_date2
, sorgu çok daha basit hale getirilebilir, ancak durumun bu olup olmadığından emin değilim).
post_author
vepost_date
benzersiz bir sıra elde etmek için yeterli değil, bu yüzden başına benzersiz bir sıra elde etmek için daha fazlası olmalıpost_author