복붙노트

[SQL] 선택 목록에있는 모든 열이 GROUP BY 절에 표시해야합니까

SQL

선택 목록에있는 모든 열이 GROUP BY 절에 표시해야합니까

내 강사는 말했다 :

이름이 집계 함수에서만 사용되지 않는 SELECT 목록의 모든 열 이름은 GROUP BY 절에 나타나야합니다

나는 그것이 진정한해야 이유에 대한 논리적 설명은 생각할 수 없다로서 난 그냥 이것 좀 확인을 꿔 ...

해결법

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

    1.다음을 상상해 :

    다음을 상상해 :

        A    B    C
       Cat   10   False
       Dog   25   True
       Dog   20   False
       Cat   5    False
    

    당신은 단지에 의해 A, B 및 그룹을 선택하면 - 당신의 출력은 어떤 것입니까? 당신은 두 행 (또는 튜플) 당신은 두 가지 값을 가지고 있기 때문에 거라고 -하지만 어떻게 B를 표시합니까?

    A, B에 의해 그룹화, 당신은 네 개의 행, 거기에 아무런 문제를 얻을하세요. 당신은 A 군에 의하여와 B의 기능을 수행하는 경우 - SUM (B) 다음 두 행을 다시 얻을 같은 :

        Cat    15
        Dog    45
    

    당신은에 의해 A, B 만 그룹을 선택한다면 - 그것은 무엇을 해야할지하지 않습니다. 솔직히, 그 경우 B에 대한 임의의 값을 선택합니다 거기 일부 데이터베이스가 믿고 난 당신에게 오류 메시지를 줄 것이다 몇 가지가있다 생각합니다.

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

    2.즉 역사적 사실입니다. 부정 행위에 집계되지 않은 열 리드를 생략. 완전히 확정 행동에서 SQL 것을 목표로하고있다.

    즉 역사적 사실입니다. 부정 행위에 집계되지 않은 열 리드를 생략. 완전히 확정 행동에서 SQL 것을 목표로하고있다.

    그러나 SQL 표준은 최근에 당신이 GROUP BY에있는 컬럼에 기능적으로 의존 절 열은 GROUP BY에서 생략 할 수 있도록 변경되었습니다. PostgreSQL은보다 최근의 SQL 표준을 따릅니다. (그것은 유일한 아니다.) 행동이 아직 완전히 확정이다.

    create table a (
      a_id integer primary key,
      xfr_date date not null
    );
    
    create table b (
      a_id integer not null references a (a_id),
      recd_date date not null,
      units_recd integer not null 
        check (units_recd >= 0),
      primary key (a_id, recd_date)
    );
    
    select a.a_id, a.xfr_date, sum(b.units_recd)
    from a
    inner join b on a.a_id = b.a_id
    group by a.a_id; -- The column a.xfr_date is functionally dependent 
                     -- on a.a_id; it doesn't have to appear in the 
                     -- GROUP BY clause.
    

    SQL 표준에서에서 주목할만한 편차는 MySQL을합니다. 그것은 당신이 단지 그룹 BY에서 모든 것을 생략 할 수 있습니다. 당신이 SELECT 목록에있는 열을 생략 할 때 그 디자인 선택은 그 동작을 확정한다.

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

    3.사실, MySQL의에서 모든 열을 그룹화 할 필요가 없습니다. 당신은 당신이 원하는대로 열로 불과 그룹을 할 수 있습니다. 문제는 단지에 의해 그룹에없는 필드 (그룹에서 사용 가능한 행 집합)에서 랜덤 값을 끌어이다. 당신이 고유 키 무언가에 의해 그룹화되는 것을 알고 있다면, 그들은 이미 모든 어쨌든 같은 값을가집니다로, 나머지 필드에 의해 그룹화 이유가 없다. 실제로 완전히 불필요 할 때마다 필드에 의해 그룹에하지에 속도를 높일 수 있습니다.

    사실, MySQL의에서 모든 열을 그룹화 할 필요가 없습니다. 당신은 당신이 원하는대로 열로 불과 그룹을 할 수 있습니다. 문제는 단지에 의해 그룹에없는 필드 (그룹에서 사용 가능한 행 집합)에서 랜덤 값을 끌어이다. 당신이 고유 키 무언가에 의해 그룹화되는 것을 알고 있다면, 그들은 이미 모든 어쨌든 같은 값을가집니다로, 나머지 필드에 의해 그룹화 이유가 없다. 실제로 완전히 불필요 할 때마다 필드에 의해 그룹에하지에 속도를 높일 수 있습니다.

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

    4.간단한 대답은 그래서 : 그것은 의존한다. MySQL은 Vertica는 그것을 허용하지 않습니다.

    간단한 대답은 그래서 : 그것은 의존한다. MySQL은 Vertica는 그것을 허용하지 않습니다.

    이 생략에 대한 올바른 사용 사례는 실제로 당신은 이미 () MIN으로 말을 선택하는 때이다.

    여기서 이벤트 추적하는 실제 예이다. 이미징 당신은 신용 및 구매 이벤트가 있습니다.

    단순화를 위해 우리는 = 신용, B, C, D는 구매 이벤트의 일종 말하는, 시간은 실행 번호로 추적됩니다. 이제 각 신용 후 첫 구매 일을 찾고 싶어요. 우리는 또한 하나의 고객 공을 가지고하는 일 :

    create table events (user_id int ,created_at int, event varchar(255));
    insert into events values (0,0, 'a');
    insert into events values (0,1, 'b');
    insert into events values (0,2, 'c');
    insert into events values (0,3, 'a');
    insert into events values (0,4, 'c');
    insert into events values (0,5, 'b');
    insert into events values (0,6, 'a');
    insert into events values (0,7, 'a');
    insert into events values (0,8, 'd');
    
    mysql> SELECT user_id, MAX(purchased) AS purchased, spent, event FROM (SELECT e1.User_ID AS user_id, e1.created_at AS purchased, MIN(e2.created_at) AS spent, e2.event AS event FROM events e1, events e2 WHERE e1.user_id = e2.user_id AND e1.created_at <= e2.created_at AND e1.Event = 'a' AND e2.Event != 'a' GROUP BY e1.user_id, e1.created_at) e3 GROUP BY user_id, spent;
    +---------+-----------+-------+-------+
    | user_id | purchased | spent | event |
    +---------+-----------+-------+-------+
    |       0 |         0 |     1 | b     |
    |       0 |         3 |     4 | c     |
    |       0 |         7 |     8 | d     |
    +---------+-----------+-------+-------+
    3 rows in set (0.00 sec)
    

    , MySQL의 좋은 보이는 Vertica의에 일을하지 않습니다 :

    ERROR 2640 : 열은 "e2.event"GROUP BY 절에 나타나야합니다 또는 집계 함수에 사용

    내가 이벤트 열을 생략하면, 그것은 모두에서 작동하지만 실제로 특정 값 이벤트가 분을 선택하는 행에 대해 가지고 무엇을 알고 싶어.

    코멘트 : 어떤 아이디어에 대한 요청과 함께 내 대답은 종료 그래서?

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

    5.당신이 뭔가에 그룹화하는 경우 각 그룹 내에서 하나 개 이상의 값이있을 수 있으므로 비 그룹화 컬럼의 개별 값을 볼 수 없습니다. 당신이 할 수있는 모든 집계 함수 (합계, 수, 분 및 등)에 대한 보고서입니다 - 이러한 결과에서 하나의 셀에 여러 값을 결합 할 수 있습니다.

    당신이 뭔가에 그룹화하는 경우 각 그룹 내에서 하나 개 이상의 값이있을 수 있으므로 비 그룹화 컬럼의 개별 값을 볼 수 없습니다. 당신이 할 수있는 모든 집계 함수 (합계, 수, 분 및 등)에 대한 보고서입니다 - 이러한 결과에서 하나의 셀에 여러 값을 결합 할 수 있습니다.

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

    6.샘 사프란으로 언급하지만, 일반적으로 무엇을 당신의 강사 말한 것은 사실로 예외가 있습니다.

    샘 사프란으로 언급하지만, 일반적으로 무엇을 당신의 강사 말한 것은 사실로 예외가 있습니다.

    나는 2 3 열 및 그룹을 선택하면 RDBMS는 3 열이 무엇을해야합니까?

    (이것은이 MySQL을의 개발자 나타나는)하지만 내가 만들었을 것입니다 결정이나 선택을 쓸 때 내가 원하는 하나 인 RDBMS의 개발자는 추가 콜 럼을 처리하는 방법에 대한 결정을 내릴 수있다? 항상 결정은 유효 할 것인가? 나는 확실히 명시 적으로 발생해야하는 상태로 저를 강요 오라클과 같은 접근 방식을 선호합니다.

    나는 3으로 RDBS 그룹, 3, 가장 많이, 가장 큰 또는 littlest 한에서 임의의 값을 선택해야 2 3 열 및 그룹을 선택하면?

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

    7.이것은 마이클 윌의 예 / 질문에 대한 답변입니다.

    이것은 마이클 윌의 예 / 질문에 대한 답변입니다.

    SELECT 
        e3.user_id,
        MAX(e3.purchased) AS purchased, 
        e3.spent, 
        e.event
    FROM 
        events e
    INNER JOIN
    (SELECT 
        e1.user_id AS user_id, 
        MIN(e1.created_at) as spent,
        e2.created_at as purchased
     FROM
        events e1
     INNER JOIN
        (SELECT e.user_id, e.created_at from events e WHERE e.event = 'a') e2   
     ON e1.user_id = e2.user_id 
     AND e1.created_at >= e2.created_at 
     AND e1.event != 'a'
     GROUP BY e1.User_ID, e2.created_at
    ) e3 
    ON e.user_id = e3.user_id AND e.created_at = e3.spent
    GROUP BY e3.user_id, e3.spent, e.event;
    
  8. from https://stackoverflow.com/questions/5986127/do-all-columns-in-a-select-list-have-to-appear-in-a-group-by-clause by cc-by-sa and MIT license