Zasada GROUP BY dotycząca kolumn SELECT
Dlaczego każda nieagregowana kolumna musi wystąpić w GROUP BY oraz na czym polega tryb only-full-group-by
Zasada GROUP BY dotycząca kolumn SELECT to bezpłatna lekcja Coding Interview Prep na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Coding Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.
Dlaczego osoby prowadzące rozmowy zaczynają od GROUP BY
GROUP BY to temat, który podczas rozmów kwalifikacyjnych odróżnia początkujących programistów od osób na poziomie średniozaawansowanym. Najczęściej sprawdzana zasada brzmi: każda kolumna na liście SELECT musi znajdować się w funkcji agregującej albo być wymieniona w GROUP BY.
Jeśli ta zasada zostanie złamana, silnik nie może zdecydować, którą wartość wyświetlić dla grupy zawierającej wiele wierszy. Osoby prowadzące rozmowy często celowo umieszczają ten błąd, aby sprawdzić, czy rozumieją Państwo, czym naprawdę jest grupa.
Czym właściwie jest grupa
GROUP BY redukuje wiele wierszy do jednego wiersza dla każdego odrębnego klucza. Po pogrupowaniu silnik nie ma już pojedynczych wierszy. Ma tylko jeden wiersz podsumowania na grupę.
- Kolumny użyte do grupowania mają jedną jednoznaczną wartość w każdej grupie.
- Agregaty takie jak
COUNT,SUM,AVGredukują wiele wartości do jednej. - Każda inna nieagregowana kolumna jest niejednoznaczna: która z wielu wartości powinna się pojawić?
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;Klasyczny błąd
Oto błąd, który osoby prowadzące rozmowy szczególnie lubią. Grupują Państwo według department, ale wybierają także name — nieagregowaną kolumnę, której nie ma w GROUP BY.
Każdy dział ma wielu pracowników, a więc w każdej grupie znajduje się wiele nazwisk. Silnik nie może wybrać jednego z nich, dlatego standard SQL odrzuca zapytanie.
-- ERROR: name is not in GROUP BY and not aggregated
SELECT department, name, COUNT(*)
FROM employees
GROUP BY department;Dwa sposoby naprawy
Istnieją dwa poprawne rozwiązania, a podczas rozmowy kwalifikacyjnej warto zaznaczyć, że prowadzą one do różnych odpowiedzi:
- Dodać kolumnę do GROUP BY, jeśli rzeczywiście potrzebują Państwo dokładniejszego podziału na grupy (jeden wiersz na dział i nazwisko).
- Użyć funkcji agregującej, takiej jak
MAX(name)lubCOUNT(name), jeśli potrzebna jest jedna wartość dla istniejącej grupy.
-- Finer grouping
SELECT department, name, COUNT(*) AS rows_for_person
FROM employees
GROUP BY department, name;ONLY_FULL_GROUP_BY w MySQL
Częsta pułapka: starsze wersje MySQL pozwalały wybierać kolumny nieujęte w grupowaniu i po cichu zwracały przypadkową wartość z grupy. Powodowało to błędne raporty, które wyglądały poprawnie.
Współczesny MySQL domyślnie włącza ONLY_FULL_GROUP_BY, wymuszając standardową regułę. Postgres, SQL Server i Oracle zawsze jej przestrzegały. Jeśli padnie pytanie, dlaczego zapytanie „działało na starym serwerze, a teraz przestało działać”, jest to właściwa odpowiedź.
-- Legal under ONLY_FULL_GROUP_BY because every
-- selected column is grouped or aggregated
SELECT department, MAX(hire_date) AS latest_hire
FROM employees
GROUP BY department;Wyjątek zależności funkcyjnej
Istnieje tu niuans, za pomocą którego osoby prowadzące rozmowy sprawdzają głębsze zrozumienie tematu. Jeśli grupują Państwo według klucza głównego tabeli, każda inna kolumna tej tabeli jest funkcyjnie zależna od klucza, więc ma dokładnie jedną wartość w każdej grupie.
Postgres i współczesny MySQL pozwalają wybierać te zależne kolumny bez wymieniania ich w GROUP BY. Pogrupowany klucz jednoznacznie je wyznacza, dlatego nie ma tu niejednoznaczności.
-- Legal: id is the PK, so name is determined by it
SELECT e.id, e.name, COUNT(o.id) AS orders
FROM employees e
LEFT JOIN orders o ON o.employee_id = e.id
GROUP BY e.id;Przykład: sprzedaż według regionu
Załóżmy, że trzeba przygotować raport całkowitej sprzedaży dla każdego regionu. Kluczem grupowania jest region, a miarą SUM(amount). Wszystkie pozostałe elementy muszą zostać zagregowane albo pominięte.
Zwróćmy uwagę, jak przejrzysta jest ta struktura: jeden wiersz na region, zawierający pojedynczą zsumowaną wartość. Tak wygląda każdy raport oparty na agregacji.
SELECT region,
SUM(amount) AS total_sales,
COUNT(*) AS num_orders,
AVG(amount) AS avg_order
FROM sales
GROUP BY region;Łączenie szczegółów z podsumowaniem
Podchwytliwe polecenie: „Wyświetl kwotę każdego zamówienia obok sumy dla jego regionu”. Nie można tego zrobić za pomocą zwykłego GROUP BY, ponieważ grupowanie usuwa pojedyncze wiersze.
Poprawną odpowiedzią jest funkcja okna (SUM(amount) OVER (PARTITION BY region)) albo ponowne złączenie z podzapytaniem zawierającym grupowanie. Właśnie rozpoznanie, że GROUP BY jest tu niewłaściwym narzędziem, stanowi sedno tego pytania.
-- Detail rows kept, region total added per row
SELECT order_id, region, amount,
SUM(amount) OVER (PARTITION BY region) AS region_total
FROM sales;GROUP BY i aliasy z SELECT
Czy można użyć w GROUP BY aliasu zdefiniowanego w SELECT? Zależy to od dialektu, a ta niespójność jest dokładnie tym, co sprawdzają osoby prowadzące rozmowy.
- MySQL i Postgres: pozwalają grupować według aliasu z SELECT.
- SQL Server i Oracle: nie pozwalają na to; trzeba powtórzyć całe wyrażenie.
Przenośnym rozwiązaniem jest powtórzenie wyrażenia w GROUP BY, ponieważ działa ono wszędzie.
-- Portable: repeat the expression rather than the alias
SELECT EXTRACT(YEAR FROM order_date) AS yr, COUNT(*)
FROM sales
GROUP BY EXTRACT(YEAR FROM order_date);DISTINCT a GROUP BY w przypadku unikatowości
Jeśli potrzebują Państwo tylko unikatowych kombinacji i nie używają agregacji, GROUP BY bez funkcji agregujących działa tak jak DISTINCT. Osoby prowadzące rozmowę mogą zapytać, które rozwiązanie jest bardziej czytelne.
Należy użyć DISTINCT, aby wyrazić zamiar („chcę unikatowych wierszy”). GROUP BY warto zachować na sytuacje, w których obliczają Państwo również agregaty. Wynik jest taki sam, ale czytelność przekazu inna.
-- These return the same rows
SELECT DISTINCT department, role FROM employees;
SELECT department, role FROM employees GROUP BY department, role;Jak o tym mówić podczas rozmowy kwalifikacyjnej
W przypadku pytania o GROUP BY warto głośno przedstawić zasadę: „Każda wybrana kolumna jest albo kluczem grupowania, albo została ujęta w funkcji agregującej, ponieważ grupowanie pozostawia jeden wiersz na klucz”.
Następnie należy wskazać klucz grupowania i miary oraz potwierdzić, że żadna kolumna nie została użyta bez grupowania. Tak uporządkowana odpowiedź sygnalizuje kompetencje na poziomie średniozaawansowanym, jeszcze zanim zostanie napisane zapytanie.
Szybkie sprawdzenie
Proszę sprawdzić, czy rozumieją Państwo podstawową zasadę GROUP BY.
Podsumowanie
Zasada: każda kolumna w SELECT musi być kluczem grupowania albo być objęta funkcją agregującą. Dlaczego: GROUP BY pozostawia jeden wiersz na każdy klucz, więc niezgrupowane kolumny surowe są niejednoznaczne.
- Naruszenia należy naprawić, grupując daną kolumnę albo stosując na niej funkcję agregującą.
- Starsze zachowanie MySQL zwracało przypadkowe wartości;
ONLY_FULL_GROUP_BYwymusza zgodność ze standardem. - Zależność funkcyjna względem klucza głównego jest jedynym legalnym wyjątkiem.
- Aby zachować wiersze szczegółowe obok sum grup, należy użyć funkcji okna, a nie GROUP BY.
Często zadawane pytania
Czy lekcja „Zasada GROUP BY dotycząca kolumn SELECT” jest bezpłatna?
Tak — pełny tekst „Zasada GROUP BY dotycząca kolumn SELECT” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Coding Interview Prep, przejdź na CoddyKit PRO. Kurs Coding Interview Prep zawiera 4 lekcji w sumie.
Co nauczysz się w „Zasada GROUP BY dotycząca kolumn SELECT”?
Dlaczego każda nieagregowana kolumna musi wystąpić w GROUP BY oraz na czym polega tryb only-full-group-by Ćwiczysz Coding Interview Prep z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Coding Interview Prep?
Nie wymagamy żadnego doświadczenia. Coding Interview Prep w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Zasada GROUP BY dotycząca kolumn SELECT”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Coding Interview Prep?
Tak. Każda lekcja Coding Interview Prep zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Zasada GROUP BY dotycząca kolumn SELECT
- HAVING a WHERE
- Grupowanie według wielu kolumn i wyrażeń
- Zliczanie i filtrowanie grup