[ROZWIĄZANY] Teradata: [Error 3504] [SQLState HY000] Selected non-aggregate values must be part of the associated group.

[ROZWIĄZANY] Teradata: [Error 3504] [SQLState HY000] Selected non-aggregate values must be part of the associated group.
Photo by John Schnobrich on Unsplash

W niniejszym poście wyjaśnię dlaczego podczas wykonywania polecenia SQL w Teradata napotkaliście błąd: [Error 3504] [SQLState HY000] Selected non-aggregate values must be part of the associated group, przedstawię przyczynę problemu oraz pokażę jak uniknąć błędu w przyszłości.

Problem

Błąd 3504 powstaje podczas grupowania danych w Teradacie z użyciem polecenia GROUP BY. Niezależnie, czy piszesz tylko polecenie DML (SELECT), czy używasz go podczas operacji DDL (np. CREATE VIEW), dostaniesz ten sam błąd. Oto najprostszy sposób na otrzymanie komunikatu błędu: 

SELECT EMPLOYEE_ID, AVG(SALARY)
FROM EMPLOYEES
ORDER BY 1;

Celem powyższego zapytania jest wyliczenie średniej pensji dla pracownika. Jednak, czegoś tam chyba brakuje..

Brak polecenia GROUP BY

Używając funkcji grupujących (np. SUM, COUNT, AVG) musisz pamiętać o zastosowaniu klauzuli GROUP BY pomiędzy poleceniem WHERE a HAVING / ORDER BY. Kolejność poleceń podczas grupowania jest następująca:

  1. SELECT  <table1.attributes>, AVG(attribute)
  2. FROM table1
  3. JOIN (INNER JOIN / LEFT/ RIGHT/ FULL OUTER JOIN) table2
  4. ON table1.attribute=table2.attribute
  5. WHERE <condition>
  6. GROUP BY <attributes>
  7. HAVING <condition>
  8. ORDER BY <attributes>

Jest oczywiście wyjątek, kiedy nie musimy używać polecenia GROUP BY – grupowanie danych bez używania dodatkowych atrybutów.

Niepoprawna liczba atrybutów

Problem Selected non-aggregate values must be part of the associated group może także wystąpić jeśli masz już polecenie GROUP BY w zapytaniu i oznacza wtedy, że lista argumentów w klauzuli GROUP BY jest niekompletna, tzn. nie wszystkie argumenty, które nie są używane z funkcjami grupującymi zostały zawarte w GROUP BY, np.:

SELECT EMPLOYEE_ID, YEAR, AVG(SALARY)
FROM EMPLOYEES
GROUP BY EMPLOYEE_ID
ORDER BY 1,2;

W powyższym zapytaniu, po instrukcji SELECT mamy 2 atrybuty EMPLOYEE_ID i YEAR, które nie są używane z funkcjami grupującymi. Natomiast po instrukcji GROUP BY mamy tylko atrybut EMPLOYEE_ID – to nie będzie działać.

Rozwiązanie

Zawsze używaj klauzuli GROUP BY przy funkcjach grupujących

W praktyce bardzo rzadko używa się zapytań z funkcjami grupującymi bez dodatkowych atrybutów, np.: 

SELECT SUM(SALARY)
FROM EMPLOYEES;

Z pewnością są pomocne podczas testów lub poszukując ogólnych sum lub ilości np. klientów od początku istnienia firmy. Zazwyczaj jednak potrzebujemy bardziej skomplikowanych wyliczeń. Zawsze pamiętaj więc o podawaniu klauzuli GROUP BY.

Upewnij się, czy lista argumentów jest poprawna

Zawsze upewnij się, czy lista argumentów po poleceniu SELECT jest zgodna z listą atrybutów w poleceniu GROUP BY, np.:

SELECT EMPLOYEE_ID, YEAR, AVG(SALARY)
FROM EMPLOYEES
GROUP BY EMPLOYEE_ID, YEAR
ORDER BY 1,2;

Jeśli spodobał Ci się ten post to zostaw proszę komentarz poniżej lub udostępnij ten post na swoim Facebook’u, Twitter’ze, LinkedIn lub innej stronie z mediami społecznościowymi.
Dzięki!

Leave a Reply

avatar
  Subscribe  
Powiadom o
Close Menu