GROUP BY 절에 나타나거나 집계 함수에서 사용해야 합니다.
이 발신자 '메이커'처럼 생긴 테이블이 있습니다.
cname | wmname | 평균의 |
---|---|---|
캐나다의 | 조로 | 2.0000000000000000 |
스페인의 | 울퉁불퉁한 | 1.00000000000000000000 |
스페인의 | usopp | 5.0000000000000000 |
그리고 각 cname에 대한 최대 avg를 선택하고 싶습니다.
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 | 맥스. |
---|---|---|
캐나다의 | 조로 | 2.0000000000000000 |
스페인의 | 울퉁불퉁한 | 1.00000000000000000000 |
스페인의 | usopp | 5.0000000000000000 |
실제 결과는 다음과 같아야 합니다.
cname | wmname | 맥스. |
---|---|---|
캐나다의 | 조로 | 2.0000000000000000 |
스페인의 | usopp | 5.0000000000000000 |
이 문제를 해결하려면 어떻게 해야 합니까?
참고: 이 표는 이전 작업에서 만든 VIEW입니다.
예, 이것은 일반적인 집계 문제입니다.SQL3(1999) 이전에는 선택한 필드가 다음에 나타나야 합니다.GROUP BY
조항[*]
이 문제를 해결하려면 하위 쿼리에서 집계를 계산한 다음 해당 집계와 결합하여 표시해야 하는 추가 열을 얻어야 합니다.
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
;
이 방법을 사용하면 모든 레코드가 표시됩니다(창 기능이 그룹화되지 않음).그러나 올바른 값(즉, 최대 값)이 표시됩니다.cname
수평)MAX
각 행에 있는 국가를 위해, 그래서 그것은 당신에게 달려 있습니다:
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
[*]: 흥미롭게도, 비록 스펙이 그룹화되지 않은 분야를 선택할 수 있지만, 주요 엔진들은 그것을 별로 좋아하지 않는 것 같습니다.Oracle 및 SQL Server에서는 이를 전혀 허용하지 않습니다.Mysql은 기본적으로 허용했지만, 5.7 이후로 관리자는 이 옵션을 활성화해야 합니다.ONLY_FULL_GROUP_BY
) 이 기능이 지원될 서버 구성에서 수동으로...
Postgres에서는 다음과 같은 특수 구문도 사용할 수 있습니다.
SELECT DISTINCT ON (cname)
cname, wmname, avg
FROM
makerar
ORDER BY
cname, avg DESC ;
에서 그룹화되지 않은 필드와 집계되지 않은 필드를 지정할 때 문제가 발생했습니다.group by
이 경우 엔진이 반환해야 하는 레코드의 필드를 알 수 없는 경우를 선택합니다.처음인가요?마지막인가요?일반적으로 집계 결과에 자연스럽게 해당하는 기록은 없습니다(min
그리고.max
예외).
그러나 필요한 필드도 집계해야 하는 해결 방법이 있습니다.사후 처리에서는 다음과 같이 작동해야 합니다.
SELECT cname, (array_agg(wmname ORDER BY avg DESC))[1], MAX(avg)
FROM makerar GROUP BY cname;
이렇게 하면 모든 wnames 배열이 생성되고 avg 순으로 정렬되며 첫 번째 요소가 반환됩니다(포스트gres 배열은 1 기반).
저는 "일반적인 집계 문제"에 대한 것이 아니라 잘못된 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
쿼리를 할 때 과 같습니다.SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
?요▁it까▁be▁should럴?spain+luffy
또는spain+usopp
왜? 쿼리에서 여러 개가 적합한 경우 "더 나은" wmname을 선택하는 방법이 결정되지 않으므로 결과도 결정되지 않습니다.그렇기 때문에 SQL 인터프리터에서 오류를 반환합니다. 쿼리가 올바르지 않습니다.
즉, "그룹 내에서 누가 최고인가?"라는 질문에는 정답이 없습니다.루피는 usopp보다 낫지 않습니다, 왜냐하면 usopp는 같은 "점수"를 가지고 있기 때문입니다.
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;
용사를 합니다.rank()
창 기능:
SELECT cname, wmname, avg
FROM (
SELECT cname, wmname, avg, rank()
OVER (PARTITION BY cname ORDER BY avg DESC)
FROM makerar) t
WHERE rank = 1;
메모
둘 중 하나는 그룹당 여러 개의 최대값을 보존합니다.max와 같은 평균 레코드가 둘 이상 있더라도 그룹당 하나의 레코드만 원한다면 @ypercube의 응답을 확인해야 합니다.
이것도 효과가 있는 것 같습니다.
SELECT *
FROM makerar m1
WHERE m1.avg = (SELECT MAX(avg)
FROM makerar m2
WHERE m1.cname = m2.cname
)
최근에 다음을 사용하여 계산하려고 할 때 이 문제가 발생합니다.case when
그리고 그것의 순서를 바꾼다는 것을 발견했습니다.which
그리고.count
문으로 문제를 해결할 수 있습니다.
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
언급URL : https://stackoverflow.com/questions/19601948/must-appear-in-the-group-by-clause-or-be-used-in-an-aggregate-function
'source' 카테고리의 다른 글
불투명 컨트롤이 포함된 투명 배경의 WPF 창 (0) | 2023.05.22 |
---|---|
어떤 버전의 MVC를 사용하고 있습니까? (0) | 2023.05.22 |
PowerShell을 사용하여 응용 프로그램을 제거하려면 어떻게 해야 합니까? (0) | 2023.05.22 |
ASP.Net: 시스템 사용.웹.UI.컨트롤.공유/정적 함수에서 Url() 확인 (0) | 2023.05.22 |
몽구스:스키마 대 모델? (0) | 2023.05.22 |