Някои хора полагат много усилия, за да избегнат клаузите GROUP BY и HAVING в своите заявки. Съобщенията за грешки са придирчиви, но обикновено са прави. GROUP BY и HAVING ключови думи са от съществено значение за доброто отчитане на SQL.
Основната причина за GROUP BY е да намали броя на редовете, обикновено чрез агрегиране. Той произвежда само един ред за всяко съвпадащо групиране от входа. Това ви позволява да правите сложни изчисления чрез обикновен SQL.
Пример за плодове:
Имаме малко плодове:
Следващият случай ни позволява да гледаме напред. В средата на годината какви плодове ще бъдат налични? Правим това със същата заявка като по-горе, но след като заявката се изпълни, ние проверяваме стойностите на min(fresh_until), като използваме клауза за наличие. HAVING е начинът, по който квалифицирате агрегат.
Всички ябълки и грозде ще бъдат налични в средата на годината.
Списъкът с елементи между SELECT и FROM, целевият списък. може да съдържа неагрегати и агрегати. Тези неагрегирани колони в целевия списък
трябва да са в група по клауза. Съобщението за грешка казва така. Редът на колоните в групата по клауза има значение. Той определя как са групирани агрегатите. Редът често е йерархичен. Това, което означава за вашите колони, е вашият фокус. Може да са плодове, източници и/или свежи_до дата.
Примери за карти за игра
Нека разгледаме друг набор от примери, които илюстрират извличането на информация за карти за игра. Можете да научите за картите в стандартните карти на Wikipedia.
Да предположим, че раздавате програмно шест ръце с 5 карти, като шестима души, които играят покер. В тази сделка се използват общо 30 карти. Те са в ръка таблица като следната, където имената на карти и костюми са обединени от справочни таблици. Ние съхраняваме ранговете, за да можем да сортираме правилно. Използваме имена за показване. Имената и ранговете имат отношение едно към едно за всяка от карти и бои.
Какъв е броят на боята за всяка ръка? Ние наистина се интересуваме само от всички ръце, които имат 3 или повече карти от една боя. Това ще ни каже кой има по-добри шансове за покер флъш. Имайте предвид, че въпреки че GROUP BY изглежда предполага ORDER BY, това не е така. ORDER BY трябва да е изрично.
И така, ако погрешно групирате заявката си? Ако тази ръка масата не е групирана по ръце, тогава ще получите 30 записа от 6 ръце от 5 карти. Ако имате агрегати, те ще бъдат групирани по ред. Не е много полезно.
Ако обобщите името на картата и не включите
името на картата самостоятелно в целевия списък и опитате да поръчате по име на карта,
ще получите съобщение за грешка, че не трябва да е в
реда по клауза. Редът по клауза трябва да съдържа
елементи от група по клауза.
Ако обаче името на картата е изрично в списъка с цел,
тогава името на картата трябва да е в група по клауза и
следователно допустимо при поръчка по клауза.
Ако заявката е по боя, ще има минимум 1 или максимум 4 записа на боя за всяка от шестте ръце. Забележете, че сортираме по ранг на костюм, който
също трябва да бъде в групата по клауза. su_name и su_rank имат връзка едно към едно.
За да видим разпределението на картите в ръце, трябва да групираме по колоната за ранг на карти. Разбира се, всяка карта има 4 бои, така че няма да видите карта в повече от четири ръце.
За да надникнем и да видим кой държи аса, можем да използваме следната кратка заявка. Имайте предвид, че има клауза WHERE, която се изпълнява при събиране на редовете. HAVING се изпълнява след събиране на редовете.
Резюме
Тези примери са прости начини за оценка на известни обекти. Експериментирайте и използвайте тези прости правила.
- Ако колона е в целевия списък, а не е агрегат, тя трябва да е в клауза GROUP BY.
- Клаузите WHERE се появяват по време на процеса на подбор.
- Клаузите HAVING се появяват след завършване на агрегатите.
- В клаузата ORDER BY могат да бъдат само неагрегирани.
- Редът на клаузата GROUP BY има значение.