UFO ET IT

MySQL이 집계 함수없이 "그룹 별"쿼리를 허용하는 이유는 무엇입니까?

ufoet 2020. 12. 9. 20:57
반응형

MySQL이 집계 함수없이 "그룹 별"쿼리를 허용하는 이유는 무엇입니까?


놀라움-이것은 MySQL에서 완벽하게 유효한 쿼리입니다.

select X, Y from someTable group by X

Oracle 또는 SQL Server에서이 쿼리를 시도하면 자연 오류 메시지가 표시됩니다.

Column 'Y' is invalid in the select list because it is not contained in 
either an aggregate function or the GROUP BY clause.

그렇다면 MySQL은 각 X에 대해 표시 할 Y를 어떻게 결정합니까? 하나만 선택합니다. 내가 알 수있는 바에 따르면, 발견 한 첫 번째 Y를 선택합니다. 근거는 Y가 집계 함수도 아니고 group by 절도 아닌 경우 쿼리에서 "select Y"를 지정하는 것은 시작하기에 의미가 없습니다. 따라서 나는 데이터베이스 엔진으로서 내가 원하는 것을 반환하고 당신은 그것을 좋아할 것입니다.

이 "느슨 함"을 해제하는 MySQL 구성 매개 변수도 있습니다. http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by

이 기사에서는 이와 관련하여 MySQL이 ANSI-SQL을 준수하지 않는다는 이유로 어떻게 비판을 받았는지 언급합니다. http://www.oreillynet.com/databases/blog/2007/05/debunking_group_by_myths.html

내 질문은 : MySQL이 이런 방식으로 설계된 이유무엇 입니까? ANSI-SQL을 중단 한 이유는 무엇입니까?


한 필드로 그룹화하면 다른 필드도 그룹화됨을 의미하는 경우를 처리하는 것이라고 생각합니다.

SELECT user.id, user.name, COUNT(post.*) AS posts 
FROM user 
  LEFT OUTER JOIN post ON post.owner_id=user.id 
GROUP BY user.id

이 경우 user.name은 항상 user.id마다 고유하므로 GROUP BY에서 user.name을 요구하지 않는 편리함이 있습니다 (말했듯이 문제에 대한 명확한 범위가 있음).


이 페이지 (5.0 온라인 매뉴얼) 에 따르면 더 나은 성능과 사용자 편의를위한 것입니다.


불행히도 거의 모든 SQL 변종은 ANSI를 깨뜨리고 예측할 수없는 결과를 가져 오는 상황을 가지고 있습니다.

다른 많은 시스템이 가지고있는 "FIRST (Y)"기능처럼 취급되도록 의도 한 것처럼 들립니다.

아마도이 구조는 MySQL 팀이 후회하는 것이지만, 중단되는 애플리케이션의 수 때문에 지원을 중단하고 싶지는 않습니다.

Rob


MySQL은 집계 함수없이 GROUP BY를 사용할 때 단일 열 DISTINCT로 처리합니다. 다른 옵션을 사용하면 전체 결과가 구별되거나 하위 쿼리 등을 사용해야합니다. 문제는 결과가 진정으로 예측 가능한지 여부입니다.

또한 이 스레드 에는 좋은 정보가 있습니다.


mysql 참조 페이지에서 읽은 내용에 따르면 "이 기능을 사용하면 불필요한 열 정렬 및 그룹화를 피함으로써 더 나은 성능을 얻을 수 있습니다. 그러나이 기능은 주로 GROUP에 이름이 지정되지 않은 각 비 집계 열의 모든 값에 유용합니다. BY는 각 그룹에 대해 동일합니다. "

이 페이지 (mysql 참조 매뉴얼 링크)를 읽어 보시기 바랍니다. http://dev.mysql.com/doc/refman/5.5/en//group-by-extensions.html


필드별로 그룹화 할 때 다른 모든 필드가 집계 함수에있을 필요가 없다는 사실은 매우 유용한 도구입니다. 먼저 순서를 지정한 다음 그룹화하여 반환 될 결과를 조작 할 수 있습니다. 예를 들어 사용자 로그인 정보를 얻고 싶고 사용자가 마지막으로 로그인 한 시간을보고 싶다면이 작업을 수행합니다.

테이블

USER
user_id | name

USER_LOGIN_HISTORY 
user_id | date_logged_in

USER_LOGIN_HISTORY에는 한 사용자에 대한 여러 행이 있으므로 사용자를 가입하면 많은 행이 반환됩니다. 나는 마지막 항목에만 관심이 있기 때문에 이것을 할 것입니다

select 
  user_id,
  name,
  date_logged_in

from(

  select 
    u.user_id, 
    u.name, 
    ulh.date_logged_in

  from users as u

    join user_login_history as ulh
      on u.user_id = ulh.user_id

  where u.user_id = 1234

  order by ulh.date_logged_in desc 

)as table1

group by user_id

그러면 사용자 이름과 사용자가 마지막으로 로그인 한 시간이 포함 된 한 행이 반환됩니다.

참고 URL : https://stackoverflow.com/questions/1225144/why-does-mysql-allow-group-by-queries-without-aggregate-functions

반응형