2013-02-27 3 views
1

다음 문장이 MySQL에서는 작동하지만 Oracle에서는 "GROUP BY가 아닌 표현식"을받는 이유는 누구든지 Oracle의 한계를 설명 할 수 있습니까? 오라클이 order_datetime 열을 처리하는 방법을 알고하지 않기 때문에 그것은Oracle vs MySQL - 집계 함수

SELECT order1.user_id, 
     order1.order_datetime, 
     SUM(order2.order_total) 
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id 
GROUP BY order1.user_id 

인가? MySQL에서와 마찬가지로 GROUP BY order1.user_id 행에서받은 열의 결과를 반환 할 수 없습니까?

편집 :

내가 그러나 나는 MySQL은 (반면에게 MySQL이 필요하지 않습니다 않는 한 오라클은 유사한 결과를 반환하지 않는 이유를 이해하기 위해 노력하고있어, 모든 열을하여 그룹에 있어야 이해 각 GROUP BY 및 Oracle).

+2

MySQL은 고양이를 좋아하지 않기 때문에. – Kermit

+4

MySQL은 임의의'order1.order_datetime'을 선택하는 것이 좋다고 생각하기 때문에. 가치가있는 것은 다른 심각한 데이터베이스 플랫폼에서도 쓸모없는 구문이 합법적이지 않은 것입니다. MySQL이 문법에 관한 지식이 없다고해서 그것이 옳은 것은 아닙니다. –

답변

12

오라클은 실제로 올바른 동작을 수행하고 있습니다. GROUP BY을 사용할 때 선택 목록의 항목은 GROUP BY 또는 집계 함수에 나타나야합니다.

SELECT order1.user_id, 
     order1.order_datetime, 
     SUM(order2.order_total) 
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id 
GROUP BY order1.user_id, order1.order_datetime 

MySQL은 FULL GROUP BY을 적용하지 않는 행동을 할 수있는 EXTENSION TO GROUP BY를 사용합니다. MySQL에서 이것을 사용한다고해도 order1.order_datetime의 값이 무엇인지 보장 할 수 없으며, MySQL은 단지 하나의 값을 선택하기 때문에 결과가 예상치 않게 될 수 있습니다.

목록의 모든 항목에 대해 GROUP BY 또는 집계를 사용해야하거나 위 쿼리를 다시 작성해야합니다. 당신은 다음 중 하나를 사용할 수 있습니다

order_datetime에 집계를 적용
SELECT order1.user_id, 
     min(order1.order_datetime) order_datetime, 
     SUM(order2.order_total) 
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id 
GROUP BY order1.user_id 

은 다음 날짜로 그룹이 없습니다.

SELECT order1.user_id, 
     order1.order_datetime, 
     SUM(order2.order_total) over(partition by order1.user_id) order_total 
FROM order_table order1 
JOIN order_table order2 ON order1.user_id = order2.user_id 

을 또는이 하위 쿼리를 사용하여 다시 작성 할 수 있습니다

당신은 sum() over()를 사용할 수 있습니다.

오라클에서
SELECT order1.user_id, 
    order1.order_datetime, 
    order2.order_total 
FROM order_table order1 
JOIN 
(
    select SUM(order_total) order_total, user_id 
    from order_table 
    group by user_id 
) order2 
    ON order1.user_id = order2.user_id 
+0

bluefeet - 자세한 답변을 보내 주셔서 감사합니다. group2를 사용하여 order2의 order_total과 함께 사용자 당 1 레코드 만 검색 할 수 있습니까? – Mike

+0

@Mike 내가 제공 한 마지막 쿼리는 각 사용자의 총 주문을 제공합니다.하위 쿼리를 사용하고 싶지 않고'group by order_datetime'을 원하지 않는다면, 그 컬럼 주위에 집계 함수를 사용할 수 있습니다. – Taryn

+6

@Mike 집계 함수 (예 : MIN (order1.order_datetime))를 사용하여 첫 번째 날짜 시간을 나타낼 수 있습니다. 안타깝게도 항목 그룹에 대해 물어보고 그룹 속성을 선택하는 방법을 결정하는 집계를 지정하지 않는 것이 좋습니다. 남성과 여성 그룹이있는 경우 남성 그룹의 연령과 여성 그룹의 연령을 묻는 것이 정확하지 않을 수 있습니다. 평균, 최소 또는 최대 또는 전체를 원할 수 있습니다. 그러나 그룹의 "나이"는 의미가 없다. –

0

당신이 단 하나의 열을 기준으로 그룹화 할 경우, group bySelect의 모든 열을 지정할 필요가되지 않고이 모든

SELECT order1.user_id, 
     order1.order_datetime, 
SUM(order2.order_total) OVER (PARTITION BY order1.user_id) order_total 
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id 
0

내 관련 질문 here
MySQL의를 참조하십시오 비 그룹화 기능/필드의 경우 "any"값을 표시하고 오라클은 필드 별 그룹화 기능 또는 그룹을 필요로합니다.

Mysql manual :
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal in MySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.

+2

나는 이것이 어떻게 관련되어 있는지 보지 못하거나 ... 정말로이 질문에 답합니다. – Kermit