12.19.3 MySQL의 GROUP BY 처리
표준 SQL에서는 GROUP BY
절이 포함 된 쿼리는 GROUP BY
절에서 이름이 지정되지 않은 선택 목록에서 비 - 집합 컬럼을 참조 할 수 없습니다. 예를 들어,이 쿼리 선택 목록의 name
컬럼이 GROUP BY
에 표시되지 않기 때문에 표준 SQL에서는 부정합니다.
SELECT o.custid, c.name, MAX (o.payment) FROM orders AS o, customers AS c WHERE o.custid = c.custid GROUP BY o.custid;
이 쿼리를 정당하게하려면 name
컬럼을 선택 목록에서 제거하거나 GROUP BY
절에 이름을 지정해야합니다.
MySQL에서는 선택 목록이 GROUP BY
절에서 이름이 지정되지 않은 비 집계 열을 볼 수 없도록 GROUP BY
의 사용을 확장하고 있습니다. 즉, 위의 쿼리는 MySQL에서는 정당입니다. 이 기능을 사용하면 불필요한 열 정렬 및 그룹화가 해결되기 때문에 성능을 향상시킬 수 있습니다. 그러나 이것은 주로 GROUP BY
로 이름이 지정되지 않은 각 비 - 집합 컬럼의 모든 값이 그룹별로 같은 경우에 유용합니다. 서버는 각 그룹에서 임의의 값을 자유롭게 선택할 수 있으므로 동일한 값이어야 선택한 값은 불확정입니다. 또한 ORDER BY
절을 추가해도 각 그룹에서 값의 선택에 영향을 줄 가능성은 없습니다. 값이 선택된 후 결과 집합의 정렬이 발생하지만, ORDER BY
는 서버에서 선택된 각 그룹의 값은 영향을받지 않습니다.
비슷한 MySQL 확장이 HAVING
절에 적용됩니다. 표준 SQL에서는 GROUP BY
절이 포함 된 쿼리는 GROUP BY
절에서 이름이 지정되지 않은 HAVING
절 비 - 집합 컬럼을 참조 할 수 없습니다. MySQL 확장에서는 계산을 쉽게하기 위해이 같은 컬럼에 대한 참조가 허용됩니다. 이 확장은 그룹화되지 않은 컬럼에 같은 그룹에 대한 값이 포함된다고 가정됩니다. 그렇지 않으면 결과가 불확정입니다.
MySQL GROUP BY
의 확장을 해제하려면 ONLY_FULL_GROUP_BY
SQL 모드를 활성화합니다. 따라서 표준 SQL의 동작이 활성화됩니다. GROUP BY
절에서 이름이 지정되어 있지 않은 컬럼은 집계 함수로 묶어야 선택 목록 또는 HAVING
절에서 사용할 수 없습니다.
또한 ONLY_FULL_GROUP_BY
하여 HAVING
절 별칭 사용에도 영향을받지 않습니다. 예를 들어, 다음 쿼리는 orders
테이블에서 한 번만 발생하는 name
값을 반환합니다.
SELECT name, COUNT (name) FROM orders GROUP BY name HAVING COUNT (name) = 1;
MySQL에서는 집합 컬럼에 HAVING
절에서 별칭을 사용하는 것이 허용되도록이 동작이 확장되고 있습니다.
SELECT name, COUNT (name) AS c FROM orders GROUP BY name HAVING c = 1;
ONLY_FULL_GROUP_BY
을 사용하면 MySQL 확장이 비활성화되고 HAVING
절 c
열이 집계 함수로 묶여 있지 않기 때문에 (이것은 집계 함수입니다), 「non-grouping field 'c' is used in HAVING clause」
오류가 발생합니다.
선택 목록의 확장은 ORDER BY
에도 적용됩니다. 즉, GROUP BY
절에 표시되지 않은 ORDER BY
절 비 - 집합 컬럼은 볼 수 없습니다. (단, 이미 설명했듯이, ORDER BY
에 의해, 비 - 집합 컬럼에서 어떤 값이 선택되는지는 영향을받지 않습니다. 선택한 후에 처음으로 정렬됩니다.) ONLY_FULL_GROUP_BY
SQL 모드가 활성화되어 있다면,이 확장이 적용되지 않습니다.
일부 경우에는 MIN()
및 MAX()
를 사용하면 고유하지 않은 경우에도 특정 컬럼 값을 얻을 수 있습니다. sort
컬럼에 6 자리 이내의 정수가 포함되어있는 경우 다음의 쿼리는 최소 sort
값을 갖는 행에서 column
값을 가져옵니다.
SUBSTR (MIN (CONCAT (LPAD (sort 6 '0'), column)), 7)
섹션 3.6.4 "특정 컬럼 그룹 당 최대 값이 저장되는 행" 을 참조하십시오.
표준 SQL을 따르려고하면 GROUP BY
절에 표현식을 사용할 수 없습니다. 해결 방법은 수식 별칭을 사용합니다.
SELECT id, FLOOR (value / 100) AS val
FROM tbl_name
GROUP BY id, val;
MySQL은 GROUP BY
절에 표현식을 사용하는 것이 허용되어 있기 때문에 별칭이 필요하지 않습니다.
SELECT id, FLOOR (value / 100)
FROM tbl_name
GROUP BY id, FLOOR (value / 100);