GROUP BY cümlesinde görünmeli veya bir toplama işlevinde kullanılmalıdır
Bu arayan 'makerar' gibi görünen bir tablom var;
cname | wmname | avg
--------+-------------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
Ve her bir cname için maksimum ortalamayı seçmek istiyorum.
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
ama bir hata alacağım,
ERROR: column "makerar.wmname" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
Bu yüzden bunu yapıyorum.
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname, wmname;
ancak bu amaçlanan sonuçları vermeyecektir ve aşağıdaki hatalı çıktı gösterilmektedir.
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
Gerçek Sonuçlar şöyle olmalıdır
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | usopp | 5.0000000000000000
Bu sorunu nasıl çözebilirim?
Not: Bu tablo, önceki bir işlemden oluşturulan bir GÖRÜNÜM'dür.
239
3
Evet, bu yaygın bir toplama sorunudur. SQL3 (1999)]1 öncesinde, seçilen alanlar
GROUP BY
cümlesinde görünmelidir[*].Bu sorunu aşmak için, toplamı bir alt sorguda hesaplamalı ve ardından göstermeniz gereken ek sütunları elde etmek için kendisiyle birleştirmelisiniz:
Ancak daha basit görünen pencere işlevlerini de kullanabilirsiniz:
Bu yöntemle ilgili tek şey, tüm kayıtları gösterecek olmasıdır (pencere işlevleri gruplama yapmaz). Ancak her satırdaki ülke için doğru (yani
cname
düzeyinde maksimum)MAX
değerini gösterecektir, bu yüzden size kalmış:Maksimum değerle eşleşen yalnızca
(cname, wmname)
çiftlerini göstermek için tartışmalı bir şekilde daha az zarif olan çözüm:[*]: İlginçtir ki, spesifikasyon gruplanmamış alanların seçilmesine izin verse de, büyük motorlar bundan pek hoşlanmıyor gibi görünüyor. Oracle ve SQLServer buna hiç izin vermiyor. Mysql eskiden varsayılan olarak buna izin veriyordu, ancak şimdi 5.7'den beri bu özelliğin desteklenmesi için yöneticinin sunucu yapılandırmasında bu seçeneği (
ONLY_FULL_GROUP_BY
) manuel olarak etkinleştirmesi gerekiyor...Postgres'te, özel
DISTINCT ON (expression)
sözdizimini de kullanabilirsiniz:rank()` pencere işlevi kullanarak:
Not
Her ikisi de grup başına birden fazla maksimum değeri koruyacaktır. Avg değeri max değerine eşit olan birden fazla kayıt olsa bile grup başına yalnızca tek bir kayıt istiyorsanız @ypercube'un yanıtını kontrol etmelisiniz.