it-source

GROUP BY와 DISTINCT 사이에 차이가 있습니까?

criticalcode 2023. 5. 6. 15:08
반응형

GROUP BY와 DISTINCT 사이에 차이가 있습니까?

얼마 전에 SQL에 대한 간단한 내용을 참조하십시오.

SELECT c FROM myTbl GROUP BY C

결과가 다음과 같습니다.

SELECT DISTINCT C FROM myTbl

제가 궁금한 것은 SQL 엔진이 명령을 처리하는 방식에 다른 점이 있는지, 아니면 실제로 동일한 것인지 궁금합니다.

저는 개인적으로 독특한 구문을 선호하지만, 다른 것보다 더 습관적이라고 확신합니다.

편집: 집계에 대한 질문이 아닙니다.GROUP BY집계 함수를 사용하는 것이 이해됩니다.

MusiGenesis의 답변은 앞서 언급한 질문과 관련하여 기능적으로 정확합니다. SQL Server는 "GroupBy"를 사용하고 집계 기능을 사용하지 않는 경우 실제로 의미하는 것이 "Distinct"라는 것을 인식할 수 있을 정도로 똑똑합니다. 따라서 단순히 "Distinct"를 사용한 것처럼 실행 계획을 생성합니다.

하지만, 행크의 반응에 주목하는 것이 중요하다고 생각합니다. "Group By"와 "Distinct"에 대한 무신경한 대우는 조심하지 않으면 위험한 고스트로 이어질 수 있습니다.두 SQL 쿼리 키워드 중 하나는 Aggregate와 함께 사용되어야 하는 키워드이고 다른 하나는 그렇지 않은 키워드 사이의 기능적 차이를 묻는 것이기 때문에 "Aggregate에 대한 질문이 아니다"라고 말하는 것은 완전히 올바르지 않습니다.

해머는 때때로 나사못을 박는 일을 할 수 있지만, 만약 여러분이 손에 스크류드라이버를 가지고 있다면, 굳이 신경쓸 필요가 있나요?

비유의 을 위해, (이비의목위해을적유,위해이▁(▁(을목),Hammer : Screwdriver :: GroupBy : Distinct그리고.screw => get list of unique values in a table column)

GROUP BY에서는 다과같은집함사수있용습다니할수를과 함수를 할 수 .AVG,MAX,MIN,SUM,그리고.COUNT에 ㅠㅠㅠDISTINCT중복 항목만 제거합니다.

예를 들어, 구매 기록이 여러 개 있는데 각 부서에서 지출한 비용을 알고 싶다면 다음과 같은 작업을 수행할 수 있습니다.

SELECT department, SUM(amount) FROM purchases GROUP BY department

부서의 됩니다.amount해당 부서에 대한 모든 행의 값.

중복 제거 기능의 관점과 다른 점은 무엇입니까?

다른 점을 제외하고는DISTINCT,GROUP BY그룹당 데이터를 집계할 수 있습니다(다른 많은 답변에서 언급한 바 있음). 제 의견에서 가장 중요한 차이점은 두 작업이 문에서 실행되는 작업의 논리적 순서에서 매우 다른 두 단계에서 "일치"한다는 것입니다.

가장 중요한 작업은 다음과 같습니다.

  • FROM (포함)JOIN,APPLY아래)
  • WHERE
  • GROUP BY (중복 제거 가능)
  • 집계
  • HAVING
  • 창 기능
  • SELECT
  • DISTINCT (중복 제거 가능)
  • UNION,INTERSECT,EXCEPT 제거 중복 제거 가능)
  • ORDER BY
  • OFFSET
  • LIMIT

보시다시피 각 작업의 논리적 순서는 해당 작업으로 수행할 수 있는 작업과 이후 작업에 미치는 영향에 영향을 미칩니다. 히특, 은사실그라는 은.GROUP BY"전에 시작"하는 작업SELECT을 의미합니다.

  1. 투영에 따라 달라지지 않습니다(이는 장점이 될 수 있음).
  2. 투영의 값을 사용할 수 없습니다(단점이 될 수 있음).

그것은 투영에 의존하지 않습니다.

투영에 의존하지 않는 것이 유용한 예는 고유한 값에 대해 창 함수를 계산하려는 경우입니다.

SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film
GROUP BY rating

Sakila 데이터베이스에 대해 실행하면 다음과 같은 결과를 얻을 수 있습니다.

rating   rn
-----------
G        1
NC-17    2
PG       3
PG-13    4
R        5

로는 동일한 일을 달성할 수 없습니다.DISTINCT쉽게:

SELECT DISTINCT rating, row_number() OVER (ORDER BY rating) AS rn
FROM film

이 쿼리는 "잘못된" 것이며 다음과 같은 결과를 가져옵니다.

rating   rn
------------
G        1
G        2
G        3
...
G        178
NC-17    179
NC-17    180
...

이것은 우리가 원했던 것이 아닙니다.DISTINCT작업이 "프로젝션 후에" 실행되므로 더 이상 제거할 수 없습니다.DISTINCT창 함수가 이미 계산되고 투영되었기 때문에 등급이 표시됩니다.사하기위를 사용하기 는.DISTINCT쿼리의 해당 부분을 중첩해야 합니다.

SELECT rating, row_number() OVER (ORDER BY rating) AS rn
FROM (
  SELECT DISTINCT rating FROM film
) f

참고 사항:이 특별한 경우에, 우리는 또한

SELECT DISTINCT rating, dense_rank() OVER (ORDER BY rating) AS rn
FROM film

투영의 값을 사용할 수 없습니다.

SQL의 단점 중 하나는 때때로 장황하다는 것입니다.앞서 살펴본 것과 같은 이유(즉, 운영의 논리적 순서)로 인해, 우리는 우리가 투영하는 것으로 "쉽게" 그룹화할 수 없습니다.

잘못된 SQL입니다.

SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY name

유효합니다(식 반복).

SELECT first_name || ' ' || last_name AS name
FROM customer
GROUP BY first_name || ' ' || last_name

이것도 유효합니다(표현식 중첩).

SELECT name
FROM (
  SELECT first_name || ' ' || last_name AS name
  FROM customer
) c
GROUP BY name

저는 이 주제에 대해 블로그 게시물에 더 자세히 썼습니다.

(적어도 SQL Server에서는) 차이가 없습니다.두 쿼리 모두 동일한 실행 계획을 사용합니다.

http://sqlmag.com/database-performance-tuning/distinct-vs-group

하위 쿼리가 포함된 경우 차이가 있을 수 있습니다.

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/

차이는 없습니다(Oracle 스타일).

http://asktom.oracle.com/pls/asktom/f?p=100:11:0 ::::P11_QUESTION_ID:32961403234212

사용하다DISTINCT중복 항목을 제거하려는 경우.사용하다GROUPY BY 연산자를 하려면 ( 연산자MAX,SUM,GROUP_CONCAT... 또는HAVING조항).

나는 그들의 실행에 미묘한 차이가 있을 가능성이 있다고 기대합니다.Oracle 10g에서 다음과 같은 라인을 따라 기능적으로 동등한 두 개의 쿼리에 대한 실행 계획을 확인했습니다.

core> select sta from zip group by sta;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH GROUP BY     |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

core> select distinct sta from zip;

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    58 |   174 |    44  (19)| 00:00:01 |
|   1 |  HASH UNIQUE       |      |    58 |   174 |    44  (19)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| ZIP  | 42303 |   123K|    38   (6)| 00:00:01 |
---------------------------------------------------------------------------

중간 작업은 "HASH GROUP BY"와 "HASH UNIQUE"로 약간 다르지만 예상 비용 등은 동일합니다.그런 다음 추적 기능을 사용하여 이러한 작업을 실행했는데, 두 번째 작업은 캐싱으로 인해 물리적 읽기를 수행할 필요가 없었다는 점을 제외하고는 실제 작업 수가 동일합니다.

그러나 작업 이름이 다르기 때문에 실행이 다소 다른 코드 경로를 따를 것이며, 이는 더 중요한 차이의 가능성을 열어준다고 생각합니다.

이러한 목적을 위해 DISTINCT 구문을 선호해야 한다고 생각합니다.단순한 습관이 아니라 쿼리의 목적을 더 명확하게 나타냅니다.

당신이 올린 쿼리는 동일합니다.그러나 다른 쿼리의 경우에는 사실이 아닐 수 있습니다.

예를 들어 다음과 같지 않습니다.

SELECT C FROM myTbl GROUP BY C, D

위의 의견을 모두 읽었지만 집계 비트 외에 Group By와 Distinct의 주요 차이점을 지적하는 사람은 없었습니다.

District는 모든 행을 반환한 다음 중복을 제거하는 반면 Group By는 알고리즘에 의해 읽힐 때 행을 하나씩 중복 제거합니다.

이것은 그들이 다른 결과를 낼 수 있다는 것을 의미합니다!

예를 들어, 다음 코드는 서로 다른 결과를 생성합니다.

SELECT distinct ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable

 SELECT ROW_NUMBER() OVER (ORDER BY Name), Name FROM NamesTable
GROUP BY Name

테이블에 이름이 10개 있고 그 중 1개가 다른 이름의 중복인 경우 첫 번째 쿼리는 10개의 행을 반환하는 반면 두 번째 쿼리는 9개의 행을 반환합니다.

그 이유는 그들이 다르게 행동할 수 있도록 위에서 말한 것입니다!

여러 열에 DISTINCT를 사용하면 결과 집합이 GROUP BY와 같이 그룹화되지 않으며 DISTINCT와 함께 집계 함수를 사용할 수 없습니다.

GROUP BY는 DISTINCT 기능과 구별되는(헤) 매우 구체적인 의미를 가집니다.

GROUP BY는 선택한 식을 사용하여 쿼리 결과를 그룹화하고, 집계 함수를 적용할 수 있으며, 이러한 함수는 전체 결과 집합이 아닌 각 그룹에 적용됩니다.

다음은 도움이 될 수 있는 예입니다.

다음과 같은 표가 주어질 경우:

name
------
barry
dave
bill
dave
dave
barry
john

다음 쿼리:

SELECT name, count(*) AS count FROM table GROUP BY name;

다음과 같은 출력이 생성됩니다.

name    count
-------------
barry   2
dave    3
bill    1
john    1

이는 DISTINCT를 사용하는 것과는 분명히 매우 다릅니다.결과를 그룹화하려면 GROUP BY를 사용하고, 특정 열의 고유한 목록을 원하는 경우 DISTINCT를 사용합니다.이렇게 하면 데이터베이스에서 필요에 따라 쿼리를 최적화할 수 있습니다.

집계 기능이 없는 GROUP BY를 사용하는 경우 내부적으로 GROUP BY는 DISTINCT로 처리되므로 이 경우 GROUP BY와 DISTINCT는 차이가 없습니다.

그러나 GROUP BY의 목적은 집계를 달성하는 것이기 때문에 DISTINCT 절이 제공되면 고유 레코드를 찾는 데 사용하는 것이 좋습니다.

특정 데이터에 대해 동일한 결과를 얻는 경우에도 서로 다른 의미를 가집니다.

그룹화 기준은 집계 작업에서 사용됩니다. 예를 들어 B의 개수를 C열로 구분하려는 경우와 같습니다.

select C, count(B) from myTbl group by C

구별되는 것이 소리가 나는 것입니다. 고유한 행을 얻을 수 있습니다.

sql server 2005에서는 쿼리 최적화 프로그램이 실행된 단순 예제의 차이를 최적화할 수 있는 것으로 보입니다.하지만 모든 상황에서 그것을 믿을 수 있을지는 모르겠습니다.

DISCTICT를 의미할 때는 GROUP BY를 사용하지 마십시오. 설령 그들이 동일하게 작동하더라도 말입니다.저는 당신이 쿼리에서 밀리초를 줄이려고 한다고 생각합니다. 그리고 저는 개발자 시간이 컴퓨터 시간보다 훨씬 더 비싸다는 것을 지적해야 합니다.

Teradata 관점에서:

결과 집합의 관점에서 Teradata에서 DISTINCT를 사용하든 GROUP BY를 사용하든 상관 없습니다.정답 집합은 동일합니다.

성능의 관점에서 볼 때, 그것은 같지 않습니다.

성능에 어떤 영향을 미치는지 이해하려면 DISTINCT 또는 GROUP BY로 문을 실행할 때 Teradata에서 어떤 일이 발생하는지 알아야 합니다.

DISTINCT의 경우, 행은 사전 집계를 수행하지 않고 즉시 재배포되는 반면, GROUP BY의 경우, 첫 번째 단계에서 사전 집계가 수행된 후에야 AMP에 고유한 값이 재배포됩니다.

지금은 GROUP BY가 항상 퍼포먼스의 관점에서 더 낫다고 생각하지 마세요.여러 값이 있는 경우 GROUP BY의 사전 집계 단계는 그다지 효율적이지 않습니다.Teradata는 중복을 제거하기 위해 데이터를 정렬해야 합니다.이 경우 먼저 재배포하는 것이 좋습니다. 즉, DISTINCT 문을 사용하십시오.중복된 값이 많은 경우에만 GROUP BY 문을 사용하는 것이 가장 좋습니다. 중복제거 단계가 수행된 후에는 재배포를 수행해야 합니다.

즉, Teradata에서 DISTINCT 대 GROUP BY는 다음을 의미합니다.

GROUP BY -> DISTINCT 많은 중복에 대해 -> 없음 또는 몇 개의 중복에만 해당합니다.DISTINCT를 사용할 경우 AMP의 스풀 공간이 부족할 수 있습니다.그 이유는 재배포가 즉시 실행되고 스큐잉으로 인해 AMP 공간이 부족해질 수 있기 때문입니다.

이렇게 되면 첫 번째 단계에서 중복 항목이 이미 제거되고 AMP를 통해 이동되는 데이터가 줄어들기 때문에 GROUP BY를 사용할 가능성이 높아집니다.

그 특정 질의에는 차이가 없습니다.그러나 집계 열을 추가할 경우 그룹화 기준을 사용해야 합니다.

하나의 열을 선택하기 때문에 이를 알 수 있습니다.

두 개의 필드를 선택하고 결과를 확인합니다.

Group By는 다음과 같이 사용됩니다.

SELECT name, SUM(transaction) FROM myTbl GROUP BY name

각 개인에 대한 모든 트랜잭션의 합계를 표시합니다.

'SQL the Language'의 관점에서 볼 때, 두 구성 요소는 동등하며, 여러분이 선택하는 것은 우리 모두가 해야 하는 '생활 방식' 중 하나입니다.저는 DISTINCT가 더 명시적일 수 있는 좋은 경우가 있다고 생각합니다(따라서 당신의 코드 등을 상속할 사람에게 더 배려해야 합니다). 하지만 그렇다고 해서 GROUP BY 구성이 잘못된 선택이라는 것을 의미하는 것은 아닙니다.

저는 이 'GROUP BY는 집계를 위한 것'이 잘못된 강조라고 생각합니다.설정된 함수(MAX, MIN, COUNT 등)는 생략할 수 있으므로 코더의 의도를 이해할 수 있습니다.

이상적인 최적화 도구는 동등한 SQL 구조를 인식하고 항상 그에 따라 이상적인 계획을 선택합니다.실생활에서 SQL 엔진을 선택하려면 테스트를 해야 합니다 :)

PS는 선택 절에서 DISTINCT 키워드의 위치가 다른 결과를 생성할 수 있다는 점에 주목합니다. 예를 들어 대비:

SELECT COUNT(DISTINCT C) FROM myTbl;

SELECT DISTINCT COUNT(C) FROM myTbl;

오래된 게시물인 거 알아요.하지만 우연히 toad에서 쿼리를 사용할 때 group by를 사용하여 고유한 값을 반환하는 쿼리가 있었고 Oracle 보고서는 모든 것이 정상적으로 작동했습니다. 즉, 좋은 응답 시간을 의미합니다.Oracle 9i에서 11g으로 마이그레이션했을 때 Toad의 응답 시간은 매우 짧았지만 보고서에서 이전 버전을 사용할 경우 보고서를 완료하는 데 약 35분이 걸렸습니다.

해결책은 DISTINCT를 사용하여 그룹을 변경하는 것이었고 이제 보고서는 약 30초 만에 실행됩니다.

나는 이것이 같은 상황을 가진 사람에게 유용하기를 바랍니다.

때로는 동일한 결과를 제공할 수도 있지만 다른 의미/경우에 사용됩니다.주요 차이점은 구문에 있습니다.

아래의 예를 자세히 살펴봅니다. DISTINCT중복된 값 집합을 필터링하는 데 사용됩니다.(6, cs, 9.1)과 (1, cs, 5.5)는 서로 다른 두 집합입니다.그렇게DISTINCT두 행을 하는 동시에 " " " 라고 합니다.GROUP BY Branch세트를 하나만 표시합니다.

 SELECT * FROM student; 
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    2 | mech   |  6.3 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    1 | cs     |  5.5 |
+------+--------+------+
5 rows in set (0.001 sec)

SELECT DISTINCT * FROM student; 
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    2 | mech   |  6.3 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    1 | cs     |  5.5 |
+------+--------+------+
5 rows in set (0.001 sec)

SELECT * FROM student GROUP BY Branch;
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    3 | civil  |  7.2 |
|    6 | cs     |  9.1 |
|    4 | eee    |  8.2 |
|    2 | mech   |  6.3 |
+------+--------+------+
4 rows in set (0.001 sec)

때때로 그것에 의해 성취될 수 있는 결과들.GROUP BY은 은다음통달수없다니습성할해로 할 수 .DISTINCT추가 조항이나 조건을 사용하지 않고.예를 들어 위의 경우.

와동한결얻위해기와 를 얻는 것.DISTINCT 열 을 든열이 름전에합니다로 .GROUP BY.구문적 차이를 확인해 보십시오.열만 사용할 수 있습니다.GROUP BY그 경우의 조항

SELECT * FROM student GROUP BY Id, Branch, CGPA;
+------+--------+------+
| Id   | Branch | CGPA |
+------+--------+------+
|    1 | cs     |  5.5 |
|    2 | mech   |  6.3 |
|    3 | civil  |  7.2 |
|    4 | eee    |  8.2 |
|    6 | cs     |  9.1 |
+------+--------+------+

또한 나는 알아차렸습니다.GROUP BY합니다.DISTINCT모르겠어하지만 저는 이것에 대해 확신할 수 없습니다.공급업체에 따라 다를 수 있습니다.

출처: https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by

사용 측면에서 GROUP BY는 계산할 행을 그룹화하는 데 사용됩니다.DISTINCT는 계산을 수행하지 않습니다.중복된 행은 표시되지 않습니다.

중복되지 않고 데이터를 표시하려면 항상 DISTINCT를 사용했습니다.

망고의 총 수량을 합산하는 것과 같은 계산을 하고 싶다면 GROUP BY를 사용하겠습니다.

에서, 하브이(HQL)에서,GROUP BY보다 훨씬 빠를 수 있습니다.DISTINCT전자는 표의 모든 필드를 비교할 필요가 없기 때문입니다.

https://sqlperformance.com/2017/01/t-sql-queries/surprises-assumptions-group-by-distinct 을 참조하십시오.

제가 항상 이해하는 방법은 구별을 사용하는 것은 선택한 모든 필드를 선택한 순서대로 그룹화하는 것과 같습니다.

예:

select distinct a, b, c from table;

다음과 같습니다.

select a, b, c from table group by a, b, c

기능 효율성은 완전히 다릅니다.중복 값을 제외한 "반환 값"만 선택하려면 그룹화 기준보다 구별 값을 사용하는 것이 좋습니다."그룹화 기준"에는 (정렬 + 제거)가 포함되므로, "구분"에는 (제거)가 포함됩니다.

일반적으로 사용할 수 있습니다.DISTINCT표의 특정 열에서 중복 항목을 제거합니다.

'BY'의'GROUP BY'와 같은 집계 할 수 .AVG,MAX,MIN,SUM,그리고.COUNT특정 열에서 열 이름과 it 집계 함수 결과를 동일한 열에 가져옵니다.

예:

select  specialColumn,sum(specialColumn) from yourTableName group by specialColumn;

집계 함수의 사용을 제외하고는 group by 절과 distent 절 사이에 큰 차이가 없습니다.둘 다 값을 구별하는 데 사용할 수 있지만 성능 관점에서 그룹화하는 것이 더 좋습니다.고유 키워드를 사용하면 내부적으로 실행 계획에서 볼 수 있는 정렬 작업을 사용했습니다.

간단한 예를 들어보겠습니다.

Declare @tmpresult table
(
  Id tinyint
)

Insert into @tmpresult
Select 5
Union all
Select 2
Union all
Select 3
Union all
Select 4


Select distinct 
Id
From @tmpresult

언급URL : https://stackoverflow.com/questions/164319/is-there-any-difference-between-group-by-and-distinct

반응형