[SQL] GROUP BY 절에 나타나야합니다 또는 집계 함수에 사용
SQLGROUP BY 절에 나타나야합니다 또는 집계 함수에 사용
나는 테이블을 가지고 그이 호출자 makerar '와 같은 외모
cname | wmname | avg
--------+-------------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
그리고 각 CNAME의 최대 평균을 선택합니다.
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
하지만 오류가 발생합니다,
ERROR: column "makerar.wmname" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
그래서 내가 이렇게
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname, wmname;
그러나 이것은 의도 된 결과를 제공하지 않으며, 아래 잘못된 출력을 나타낸다.
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
실제 결과는해야한다
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | usopp | 5.0000000000000000
이 문제를 어떻게 해결에 대한 갈 수 있나요?
참고 :이 표는 이전 작업에서 작성된 도면이다.
해결법
-
==============================
1.예, 이것은 일반적인 집계 문제입니다. SQL3 (1999) 전에 선택한 필드 절 [*]에 의해 GROUP에 표시해야합니다.
예, 이것은 일반적인 집계 문제입니다. SQL3 (1999) 전에 선택한 필드 절 [*]에 의해 GROUP에 표시해야합니다.
이 문제를 해결하려면, 당신은 하위 쿼리에서 집계를 계산 한 다음 보여줄 필요하려는 추가 열을 얻을 자체로 가입해야합니다 :
SELECT m.cname, m.wmname, t.mx FROM ( SELECT cname, MAX(avg) AS mx FROM makerar GROUP BY cname ) t JOIN makerar m ON m.cname = t.cname AND t.mx = m.avg ; cname | wmname | mx --------+--------+------------------------ canada | zoro | 2.0000000000000000 spain | usopp | 5.0000000000000000
그러나 당신은 또한 간단하게 보이는 창 기능을 사용할 수 있습니다 :
SELECT cname, wmname, MAX(avg) OVER (PARTITION BY cname) AS mx FROM makerar ;
이 방법의 유일한 점은 (윈도우 함수 그룹을하지 않는) 모든 레코드를 보여줄 것입니다. 그것은 당신까지, 그래서하지만, 각 행의 국가 MAX을 (CNAME 수준에서 즉 끝나가는) 올바른 표시됩니다 :
cname | wmname | mx --------+--------+------------------------ canada | zoro | 2.0000000000000000 spain | luffy | 5.0000000000000000 spain | usopp | 5.0000000000000000
용액을 틀림없이 적은 우아한 유일한 (CNAME, wmname)를 보여이고, 최대 값과 일치하는 튜플 :
SELECT DISTINCT /* distinct here matters, because maybe there are various tuples for the same max value */ m.cname, m.wmname, t.avg AS mx FROM ( SELECT cname, wmname, avg, ROW_NUMBER() OVER (PARTITION BY avg DESC) AS rn FROM makerar ) t JOIN makerar m ON m.cname = t.cname AND m.wmname = t.wmname AND t.rn = 1 ; cname | wmname | mx --------+--------+------------------------ canada | zoro | 2.0000000000000000 spain | usopp | 5.0000000000000000
[*] : 흥미롭게의 사양 종류가 아닌 그룹화 필드를 선택할 수 있습니다에도 불구하고, 주요 엔진은 정말 좋아 보인다. 오라클과의 SQLServer는 전혀이 허용되지 않습니다. MySQL은 기본적으로 허용하는 데 사용,하지만 지금은 5.7 이후 관리자 (ONLY_FULL_GROUP_BY) 수동 기능의 서버 구성에서 지원이 옵션을 사용하도록 설정해야합니다 ...
-
==============================
2.포스트 그레스, 당신은 또한 특별한 DISTINCT ON (표현) 구문을 사용할 수 있습니다 :
포스트 그레스, 당신은 또한 특별한 DISTINCT ON (표현) 구문을 사용할 수 있습니다 :
SELECT DISTINCT ON (cname) cname, wmname, avg FROM makerar ORDER BY cname, avg DESC ;
-
==============================
3.선택에 의해 그룹에서 비 그룹화 및 비 집계 필드를 지정하는 문제는 그 엔진이이 경우에 반환해야하는 레코드의 필드 알 수있는 방법이 없습니다. 먼저인가? 이 마지막인가? 자연스럽게 집계 결과 (최소 및 최대입니다 예외)에 해당하는지에 대한 기록은 일반적으로 없습니다.
선택에 의해 그룹에서 비 그룹화 및 비 집계 필드를 지정하는 문제는 그 엔진이이 경우에 반환해야하는 레코드의 필드 알 수있는 방법이 없습니다. 먼저인가? 이 마지막인가? 자연스럽게 집계 결과 (최소 및 최대입니다 예외)에 해당하는지에 대한 기록은 일반적으로 없습니다.
그러나, 해결 방법이있다 : 골재뿐만 아니라 필수 항목을합니다. 포스트 그레스,이 작업을해야합니다 :
SELECT cname, (array_agg(wmname ORDER BY avg DESC))[1], MAX(avg) FROM makerar GROUP BY cname;
참고 이것은 평균에 의해 주문 된 wnames의 배열을 생성하고, (포스트 그레스의 배열이 1 기이다)의 첫 번째 요소를 반환.
-
==============================
4.
SELECT t1.cname, t1.wmname, t2.max FROM makerar t1 JOIN ( SELECT cname, MAX(avg) max FROM makerar GROUP BY cname ) t2 ON t1.cname = t2.cname AND t1.avg = t2.max;
순위 () 윈도우 함수를 사용하여 :
SELECT cname, wmname, avg FROM ( SELECT cname, wmname, avg, rank() OVER (PARTITION BY cname ORDER BY avg DESC) FROM makerar) t WHERE rank = 1;
노트
어느 한 그룹 당 다수의 최대 값을 유지합니다. 당신은 당신이 ypercube의 대답 @ 확인해야 최대 동일한 평균 더 이상의 레코드가있는 경우에도 그룹 당 하나의 기록을합니다.
-
==============================
5.나를 위해, 그것은 그러나 다만 잘못된 SQL 쿼리에 대해,는 "일반적인 집계 문제"에 대한 없습니다. 에 대한 하나의 정답 "각 CNAME의 최대 평균을 선택은 ..."이다
나를 위해, 그것은 그러나 다만 잘못된 SQL 쿼리에 대해,는 "일반적인 집계 문제"에 대한 없습니다. 에 대한 하나의 정답 "각 CNAME의 최대 평균을 선택은 ..."이다
SELECT cname, MAX(avg) FROM makerar GROUP BY cname;
그 결과는 다음과 같습니다
cname | MAX(avg) --------+--------------------- canada | 2.0000000000000000 spain | 5.0000000000000000
일반적으로 답변에서이 결과 문제 "각 그룹에 대한 최상의 결과 무엇입니까?". 우리는 스페인의 가장 좋은 결과는 5이며, 캐나다 최선의 결과 그것은 사실이다 2.이며, 오류가없는 것을 알 수있다. 우리는 또한 wmname를 표시해야하는 경우, 우리는 질문에 답해야한다 : "세트를 결과에서 wmname를 선택할 수있는 규칙은 무엇입니까" 약간의하자의 변화 입력 데이터는 실수를 명확히 :
cname | wmname | avg --------+--------+----------------------- spain | zoro | 1.0000000000000000 spain | luffy | 5.0000000000000000 spain | usopp | 5.0000000000000000
결과이 쿼리를 runnig에 기대 어떤 : SELECT CNAME CNAME BY makerar 그룹, wmname, MAX (평균);? 그것은 스페인 + 루피 또는 스페인 + 우솝해야 하는가? 왜? 몇 가지가 적합한 경우 결과도 결정되지 않도록, "더 나은"wmname을 선택하는 방법 쿼리에서 결정되지 않습니다. 쿼리가 정확하지 않습니다 - SQL 반환 통역 오류가 이유입니다.
다른 단어에서 질문에 대한 정답이 없다 "스페인 그룹의 최고?". 우솝이 같은 "점수"를 가지고 있기 때문에 루피는 더 나은 우솝 이상이다.
-
==============================
6.나는 최근이 문제로 실행 할 때 케이스를 사용하여 계산하려고 때 발견 그 어떤 및 계산 문 수정 문제의 순서를 변경 :
나는 최근이 문제로 실행 할 때 케이스를 사용하여 계산하려고 때 발견 그 어떤 및 계산 문 수정 문제의 순서를 변경 :
SELECT date(dateday) as pick_day, COUNT(CASE WHEN (apples = 'TRUE' OR oranges 'TRUE') THEN fruit END) AS fruit_counter FROM pickings GROUP BY 1
후자에, 나는 사과와 오렌지가 집계 함수에 나타나도록 오류를 어디서 얻었 - 대신 사용
CASE WHEN ((apples = 'TRUE' OR oranges 'TRUE') THEN COUNT(*) END) END AS fruit_counter
-
==============================
7.이뿐만 아니라 작동하는 것 같다
이뿐만 아니라 작동하는 것 같다
SELECT * FROM makerar m1 WHERE m1.avg = (SELECT MAX(avg) FROM makerar m2 WHERE m1.cname = m2.cname )
from https://stackoverflow.com/questions/19601948/must-appear-in-the-group-by-clause-or-be-used-in-an-aggregate-function by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] DISTINCT와 선택 COUNT (*) - SQL 서버 쿼리 (0) | 2020.03.26 |
---|---|
[SQL] 인라인 테이블 값 함수 대 다중 문 테이블 반환 함수 (0) | 2020.03.26 |
[SQL] 이 SQL Server 데이터베이스 (스키마 및 데이터)를 비교하는 가장 좋은 도구는 무엇입니까? [복제] (0) | 2020.03.26 |
[SQL] 소프트 삭제는 좋은 아이디어인가? [복제] (0) | 2020.03.26 |
[SQL] 저장 프로 시저 SQL VS ADO.NET에 엔티티 프레임 워크 VS LINQ? [닫은] (0) | 2020.03.26 |