복붙노트

[SQL] 더 집계 함수는 SELECT 절에 존재하지 않는 GROUP BY 동작

SQL

더 집계 함수는 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

무엇을 기준으로 서버는 반환 질 프레드을 결정하고 잭과 톰를 제외 했습니까?

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

주 1 : 나는 스스로 이해가되지 않습니다 쿼리를 알고있다. 나는 'GROUP BY'시나리오에 문제를 디버깅하는 것을 시도하고있다. 나는이 목적을 위해 기본 동작을 이해하려고 노력하고 있습니다.

주 2 : 나는 GROUP BY 절 (마이너스 집계 필드)과 동일한 SELECT 절을 작성하는 데 사용하고있다. 내가 위에서 설명한 동작을 가로 질러 왔을 때, 나는 다음과 같은 시나리오이에 의존 할 수 있는지 궁금 시작 :    급여는 부서에서 / 가장 높은 곳 EMP 테이블의 행을 선택한다. 예컨대 : MySQL의에이 작품과 같은 SQL 문 :

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)

해결법

  1. ==============================

    1.이 특정 시점에 MySQL의 설명서를 참조하십시오.

    이 특정 시점에 MySQL의 설명서를 참조하십시오.

    간단히 말해서, MySQL은 그러나이 생략 된 열이 모두 같은 값이있는 경우에만 작동, 성능 목적으로는 GROUP BY에서 일부 열을 생략 할 수 있습니다

  2. ==============================

    2.이것은 조금 늦게,하지만 난 미래의 참조를 위해이를 놓을 게요.

    이것은 조금 늦게,하지만 난 미래의 참조를 위해이를 놓을 게요.

    그룹이 중복 파기 어떤 행이 첫 번째 행을 소요하는 결과 집합이 후 일치합니다. 그래서 잭과 톰은 GROUP BY의 결과 행이 될 것입니다 일반 SELECT에 처음 나타나는 누구든지 같은 부서가있는 경우.

    이 목록에 처음 표시되는 내용을 제어하려면, 다음과 같은 방법으로 주문을 할 필요가있다. 그러나, SQL은 예외가 발생합니다으로 ORDER BY는 GROUP BY 앞에 오는 것을 허용하지 않습니다. 이 문제에 대한 가장 좋은 해결 방법은 외부 쿼리에서 다음 하위 쿼리 및 GROUP BY에 의해 주문을하는 것입니다. 다음은 그 예이다 :

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

    이것은 내가 찾은 최고의 수행하는 기술이다. 나는이 사람의 밖으로 도움이되기를 바랍니다.

  3. ==============================

    3.지금까지 내가 아는 한, 당신의 목적을 위해 반환 된 특정 행은 무작위로 간주 될 수있다.

    지금까지 내가 아는 한, 당신의 목적을 위해 반환 된 특정 행은 무작위로 간주 될 수있다.

    GROUP BY가 완료되면 주문에만 발생

  4. ==============================

    4.당신은 넣을 수 있습니다 :

    당신은 넣을 수 있습니다 :

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

    쿼리 전에 SQL 표준 GROUP BY 동작을 집행

  5. ==============================

    5.내가 할 수있는 가장 좋은 쿼리 지원되지 않는 이러한 유형의 고려는 사실을 알게 될 것입니다. 대부분의 다른 데이터베이스 시스템에서는 GROUP BY 절 또는 BY 절 집계 HAVING, SELECT의 기능 또는 ORDER에 하나가 아닌 컬럼을 포함 할 수 없습니다.

    내가 할 수있는 가장 좋은 쿼리 지원되지 않는 이러한 유형의 고려는 사실을 알게 될 것입니다. 대부분의 다른 데이터베이스 시스템에서는 GROUP BY 절 또는 BY 절 집계 HAVING, SELECT의 기능 또는 ORDER에 하나가 아닌 컬럼을 포함 할 수 없습니다.

    대신, 쿼리가 읽는 것을 고려하십시오

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

    ...이 무슨 일이 일어나고 있는지 때문이다.

    도움이 되었기를 바랍니다....

  6. ==============================

    6.나는 ANSI SQL은 선택이 GROUP BY 절에서 필드 만 플러스 집계 함수를 포함해야합니다 생각합니다. 반환 같은 MySQL의 외모 일부 행 가능성 서버가 읽은 마지막, 또는 손에 가지고 있던 행,하지만에 의존하지 않는이 행동.

    나는 ANSI SQL은 선택이 GROUP BY 절에서 필드 만 플러스 집계 함수를 포함해야합니다 생각합니다. 반환 같은 MySQL의 외모 일부 행 가능성 서버가 읽은 마지막, 또는 손에 가지고 있던 행,하지만에 의존하지 않는이 행동.

  7. ==============================

    7.당신이 원하는 행을 선택하는 ORDER BY를 사용해보십시오.

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

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

    다음을 반환합니다 :

    name   dept    salary
    -----  -----   -----
    jack   a       2
    fred   b       1
    
  8. ==============================

    8.당신이 부서에 의해 그룹화하는 경우는 다른 데이터에 대한 상관이야? 나는 SQL Server가도이 쿼리를 허용하지 않습니다 알고있다. 이 소리의 가능성이있는 경우 다른 문제가있을 수 있습니다처럼.

    당신이 부서에 의해 그룹화하는 경우는 다른 데이터에 대한 상관이야? 나는 SQL Server가도이 쿼리를 허용하지 않습니다 알고있다. 이 소리의 가능성이있는 경우 다른 문제가있을 수 있습니다처럼.

  9. from https://stackoverflow.com/questions/1591909/group-by-behavior-when-no-aggregate-functions-are-present-in-the-select-clause by cc-by-sa and MIT license