programing

SELECT 절에 집계 함수가 없는 경우 GROUP BY 동작

telecom 2023. 9. 7. 21:31
반응형

SELECT 절에 집계 함수가 없는 경우 GROUP BY 동작

자리가 있습니다.emp다음과 같은 구조 및 데이터를 사용합니다.

name   dept    salary
-----  -----   -----
Jack   a       2
Jill   a       1
Tom    b       2
Fred   b       1

다음 SQL을 실행할 때:

SELECT * FROM emp GROUP BY dept

저는 다음과 같은 결과를 얻습니다.

name   dept    salary
-----  -----   -----
Jill   a       1
Fred   b       1

서버가 Jill과 Fred를 돌려보내고 Jack과 Tom을 제외하기로 결정한 근거는 무엇입니까?

MySQL에서 이 쿼리를 실행하고 있습니다.

참고 1: 쿼리 자체로는 의미가 없다는 것을 알고 있습니다.'GROUP BY' 시나리오의 문제를 디버그하려고 합니다.이를 위해 기본 동작을 이해하려고 합니다.

참고 2: GROUP BY 절(aggregate fields 제외)과 같은 SELECT 절을 작성하는 것에 익숙합니다.위에서 설명한 행동을 접했을 때, 저는 다음과 같은 시나리오를 사용할 수 있을까 생각하기 시작했습니다. 다음과 같은 시나리오에서 급여가 가장 낮은 곳/가장 높은 곳의 행을 선택하십시오.예: 이와 같은 SQL 문은 MySQL에서 작동합니다.

SELECT A.*, MIN(A.salary) AS min_salary FROM emp AS A GROUP BY A.dept

이러한 SQL이 작동하는 이유를 설명하는 자료를 찾을 수 없었습니다. 이러한 동작을 지속적으로 사용할 수 있다면 더욱 중요합니다.신뢰할 수 있는 동작이면 다음과 같은 쿼리를 피할 수 있습니다.

SELECT A.* FROM emp AS A WHERE A.salary = ( 
            SELECT MAX(B.salary) FROM emp B WHERE B.dept = A.dept)

이 특정 지점에 대한 MySQL 문서를 읽습니다.

간단히 말해서, MySQL은 성능을 위해 GROUP BY에서 일부 열을 생략할 수 있지만, 이것생략된 열이 모두 동일한 값(그룹 내)을 가질 경우에만 작동하며, 그렇지 않으면 이 게시물의 다른 사람들이 적절하게 추측한 것처럼 쿼리에 의해 반환되는 값이 실제로 불확실합니다.ORDER BY 절을 추가하는 것이 어떤 형태의 결정론적 행동을 다시 도입하지는 않을 것임을 확인합니다.

문제의 핵심은 아니지만, 이 예제는 원하는 열을 명시적으로 열거하는 대신 *를 사용하는 것이 종종 나쁜 생각임을 보여줍니다.

MySQL 5.0 설명서에서 발췌한 내용:

이 기능을 사용할 경우 각 그룹의 모든 행이 동일한 값을 가져야 합니다.GROUP BY part에서 생략된 열에 대해 설명합니다.서버가 무료입니다.그룹에서 값을 반환하므로 다음과 같은 경우가 아니면 결과가 결정되지 않습니다.모든 값은 동일합니다.

조금 늦었지만, 나중에 참고할 수 있도록 올리겠습니다.

GROUP BY는 중복되는 첫 번째 행을 가져가고 결과 집합에서 그 다음에 일치하는 행을 모두 폐기합니다.따라서 잭과 톰이 같은 부서를 가진 경우 일반 SELECT에서 가장 먼저 나타나는 사람이 GROUP BY의 결과 행이 됩니다.

목록에서 가장 먼저 나타나는 것을 제어하려면 ORDER BY를 수행해야 합니다.그러나 SQL에서는 예외를 발생시키므로 ORDER BY가 GROUP BY 앞에 오는 것을 허용하지 않습니다.이 문제를 해결하는 가장 좋은 방법은 하위 쿼리에서 ORDER BY를 수행한 다음 외부 쿼리에서 GROUP BY를 수행하는 것입니다.예는 다음과 같습니다.

SELECT * FROM (SELECT * FROM emp ORDER BY name) as foo GROUP BY dept

이것은 제가 찾은 최고의 연주 기술입니다.누군가에게 도움이 되었으면 좋겠습니다.

제가 알기로는, 고객님의 목적상 반환되는 특정 행은 임의로 간주될 수 있습니다.

은 에만 이후에만 진행됩니다.GROUP BY다했습니다

다음을 입력할 수 있습니다.

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

표준 SQL을 를 수행하기 에 다음과 같이 .GROUP BY

가장 좋은 방법은 이러한 유형의 쿼리가 지원되지 않는다고 간주하는 것입니다.대부분의 다른 데이터베이스 시스템에서는 GROUP BY 절이나 HAVING, SELECT 또는 ORDER BY 절의 Aggregate 함수에 없는 열을 포함할 수 없습니다.

대신 쿼리의 내용은 다음과 같습니다.

SELECT ANY(name), dept, ANY(salary)
FROM emp 
GROUP BY dept;

...이게 바로 이 일이기 때문입니다.

이게 도움이 되길..

ANSI SQL은 선택 항목에 GROUP BY 절의 필드와 Aggregate 함수만 포함해야 한다고 생각합니다.MySQL의 이러한 동작은 서버가 마지막으로 읽은 행 또는 서버가 당면한 행을 반환하는 것처럼 보이지만 이에 의존하지 마십시오.

이렇게 하면 각 사용자에 대해 가장 최근 행이 선택됩니다.

SELECT * FROM emp
WHERE ID IN
(
    SELECT
        MAX(ID) AS ID
    FROM
        emp
    GROUP BY
        name
)

부서별로 그룹화를 한다면 다른 데이터는 상관없습니까?Sql Server가 이 쿼리조차 허용하지 않을 것이라는 것을 알고 있습니다.가능성이 있다면 다른 문제가 있을 수도 있습니다.

ORDER BY를 사용하여 원하는 행을 선택해 보십시오.

SELECT * FROM emp GROUP BY dept ORDER BY name ASC;

다음을 반환합니다.

name   dept    salary
-----  -----   -----
jack   a       2
fred   b       1

언급URL : https://stackoverflow.com/questions/1591909/group-by-behavior-when-no-aggregate-functions-are-present-in-the-select-clause

반응형