source

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

manysource 2022. 11. 23. 20:21

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가 집약함수도 아니고 그룹화 기준절에도 없는 경우 쿼리에서 "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을 사용하는 이유는 무엇입니까?

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

한 필드에 의한 그룹화가 다른 필드에도 그룹화를 의미하는 경우를 처리하기 위한 것이라고 생각합니다.

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.id마다 항상 에 user.name user.name 에서는.name 를 로 하지 .GROUP BY만)

유감스럽게도 거의 모든 SQL 변종에서 ANSI가 깨지고 예측할 수 없는 결과가 발생하는 상황이 발생합니다.

다른 많은 시스템이 가지고 있는 「FIRST(Y)」기능과 같은 취급을 의도하고 있는 것 같습니다.

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

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

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

mysql 참조 페이지에서 읽은 내용을 보면 다음과 같습니다. "이 기능을 사용하면 불필요한 열 정렬 및 그룹화를 방지하여 성능을 향상시킬 수 있습니다. 그러나 이는 주로 GROUP BY에서 이름이 지정되지 않은 각 비집약 열의 모든 값이 각 그룹에 대해 동일한 경우에 유용합니다."

이 페이지(mysql 참조 매뉴얼 링크)를 읽어보실 것을 권장합니다.http://dev.mysql.com/doc/refman/5.5/en/ / group - by - extensions . http:

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

테이블

USER
user_id | name

USER_LOGIN_HISTORY 
user_id | date_logged_in

USER_LOGIN_HISTORY는 1명의 사용자에 대해 여러 개의 행을 가지고 있기 때문에 이 행에 가입하면 여러 개의 행이 반환됩니다.마지막 엔트리에만 관심이 있기 때문에 이렇게 하겠습니다.

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

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

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