복붙노트

[SQL] 왜 MySQL은 집계 함수없이 쿼리 "에 의해 그룹을"할 수 있습니까?

SQL

왜 MySQL은 집계 함수없이 쿼리 "에 의해 그룹을"할 수 있습니까?

서프라이즈 -이 MySQL의에서 완벽하게 유효한 쿼리입니다 :

select X, Y from someTable group by X

오라클이나 SQL 서버에서이 쿼리를 시도하면 자연 오류 메시지가 것 :

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는 다음 쿼리에서 "Y를 선택"을 지정 by 절 어느 집계 함수 나 그룹에이 경우 이론적 근거의 존재는,로 시작하는 이해되지 않는다. 따라서, 나는 데이터베이스 엔진은 내가 원하는대로 돌아갑니다로서, 당신은 그것을 좋아합니다.

이 "느슨 함"을 해제 할 수있는 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과 파괴에 대한 자신의 근거는 무엇입니까?

해결법

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

    1.나는 그것이 하나 개의 필드로 그룹화하는 다른 필드는 그룹화되고 함축 경우를 처리하는 것이라고 생각 :

    나는 그것이 하나 개의 필드로 그룹화하는 다른 필드는 그룹화되고 함축 경우를 처리하는 것이라고 생각 :

    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이 필요하지 않은 편의가 (당신이 말한대로, 문제에 대한 명확한 범위가, 비록)

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

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

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

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

    3.불행하게도 거의 모든 SQL 품종은 ANSI 휴식과 예측할 수없는 결과가 상황이있다.

    불행하게도 거의 모든 SQL 품종은 ANSI 휴식과 예측할 수없는 결과가 상황이있다.

    그들은 다른 많은 시스템이 가지고있는 "FIRST (Y)"기능을 취급하기위한 것처럼 나에게 소리.

    이상 가능성이 구조는 MySQL의 팀 후회하지만, 때문에 휴식 것이 응용 프로그램의 수의 지원을 중단하지 않는 무언가이다.

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

    4.당신이 집계 함수없이 GROUP BY를 사용할 때 MySQL의 취급이 단일 열 구분된다. 등, 당신도 전체 결과는 구별되어야, 또는 하위 쿼리를 사용할 필요가 질문을 다른 옵션을 사용하면 결과는 정말 예측할 수 있는지 여부입니다.

    당신이 집계 함수없이 GROUP BY를 사용할 때 MySQL의 취급이 단일 열 구분된다. 등, 당신도 전체 결과는 구별되어야, 또는 하위 쿼리를 사용할 필요가 질문을 다른 옵션을 사용하면 결과는 정말 예측할 수 있는지 여부입니다.

    또한, 좋은 정보를 원하시면이 스레드에 있습니다.

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

    5.나는 MySQL의 참조 페이지에서 읽은 바로는, 그것은 말합니다 : "당신은 불필요한 열 정렬을 피하고 그룹화하여 더 나은 성능을 얻기 위해이 기능을 사용할 수 있습니다. 실체가에 이름이없는 각 집계되지 열의 모든 값이 각 그룹에 대해 동일 주로 그러나이 유용합니다."

    나는 MySQL의 참조 페이지에서 읽은 바로는, 그것은 말합니다 : "당신은 불필요한 열 정렬을 피하고 그룹화하여 더 나은 성능을 얻기 위해이 기능을 사용할 수 있습니다. 실체가에 이름이없는 각 집계되지 열의 모든 값이 각 그룹에 대해 동일 주로 그러나이 유용합니다."

    나는이 페이지 (MySQL의의 참조 설명서에 대한 링크)을 읽는 것이 좋습니다 : http://dev.mysql.com/doc/refman/5.5/en//group-by-extensions.html

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

    6.그 사실은 매우 유용한 도구가 그나마 다른 모든 필드가 집계 함수에있을 것을 할 때 필드로 그룹화. 당신은 단순히 후 그룹화 한 후 먼저 주문에 의해 반환되는 결과를 조작 할 수 있습니다. 예를 들어 나는 사용자 로그인 정보를 얻을 싶어하고 나는 사용자가 내가 이런 짓을 했을까에 마지막으로 로그인 한 시간을보고 싶어합니다.

    그 사실은 매우 유용한 도구가 그나마 다른 모든 필드가 집계 함수에있을 것을 할 때 필드로 그룹화. 당신은 단순히 후 그룹화 한 후 먼저 주문에 의해 반환되는 결과를 조작 할 수 있습니다. 예를 들어 나는 사용자 로그인 정보를 얻을 싶어하고 나는 사용자가 내가 이런 짓을 했을까에 마지막으로 로그인 한 시간을보고 싶어합니다.

    테이블

    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
    

    이것은 사용자의 이름과 사용자가 로그인하는 마지막 하나 개의 행을 반환합니다.

  7. from https://stackoverflow.com/questions/1225144/why-does-mysql-allow-group-by-queries-without-aggregate-functions by cc-by-sa and MIT license