[sql] SQL / mysql-distinct / UNIQUE를 선택하지만 모든 열을 반환합니까?

SELECT DISTINCT field1, field2, field3, ......   FROM table

다음 SQL 문을 달성하려고하지만 모든 열을 반환하기를 원합니까? 다음과 같은 것 :

SELECT DISTINCT field1, * from table



답변

다음을 기준으로 그룹을 찾고 있습니다.

select *
from table
group by field1

때로는 명확한 성명서로 작성할 수 있습니다.

select distinct on field1 *
from table

그러나 대부분의 플랫폼에서는 다른 열의 동작이 지정되어 있지 않으므로 위의 어느 것도 작동하지 않습니다. (첫 번째는 MySQL에서 사용하는 것입니다.)

별개의 필드를 가져와 매번 단일 임의의 행을 고를 수 있습니다.

일부 플랫폼 (예 : PostgreSQL, Oracle, T-SQL)에서는 창 기능을 사용하여 직접 수행 할 수 있습니다.

select *
from (
   select *,
          row_number() over (partition by field1 order by field2) as row_number
   from table
   ) as rows
where row_number = 1

다른 사람 (MySQL, SQLite)에서는 전체 테이블을 자체적으로 결합시킬 수있는 하위 쿼리를 작성해야 하므로 ( 예제 ) 권장하지 않습니다.


답변

귀하의 질문의 표현에서, 당신은 주어진 필드와 같은 각 행의 다른 모든 열 값이 나열된 동일한 값에 대해 다른 값을 선택하고 싶다는 것을 이해합니다. 대부분의 DBMS는이를 허용하지 DISTINCT않으며GROUP BY 결과가 결정되지 않기 때문에 .

이것을 다음과 같이 생각하십시오 : 당신 field1이 두 번 이상 발생하면, 어떤 값 field2이 나열 될 것 입니까 ( field1두 행에서 동일한 값을 가지지 만 두 행에서 두 개의 다른 값을 가지면 field2).

그러나 집계 함수 (표시하려는 모든 필드에 대해 명시 적으로)를 사용하는 GROUP BY대신 다음을 대신 사용할 수 있습니다 DISTINCT.

SELECT field1, MAX(field2), COUNT(field3), SUM(field4), .... FROM table GROUP BY field1


답변

문제를 올바르게 이해했다면 방금 한 것과 비슷합니다. DISTINCT의 유용성을 모든 데이터에 적용하지 않고 지정된 필드로 제한 할 수 있기를 원합니다.

집계 함수없이 GROUP BY를 사용하는 경우 GROUP BY 필드는 DISTINCT 파일입니다.

당신이 쿼리를하는 경우 :

SELECT * from table GROUP BY field1;

field1의 단일 인스턴스를 기반으로 모든 결과를 표시합니다.

예를 들어 이름, 주소 및 도시가있는 테이블이있는 경우입니다. 한 사람이 여러 주소를 기록했지만 그 사람을 위해 하나의 주소 만 원하면 다음과 같이 쿼리 할 수 ​​있습니다.

SELECT * FROM persons GROUP BY name;

결과적으로 해당 이름의 한 인스턴스 만 주소와 함께 표시되고 다른 인스턴스는 결과 테이블에서 생략됩니다. 주의 : 제출 한 파일에 firstName, lastName과 같은 원자 값이 있으면 둘 다 그룹화 할 수 있습니다.

SELECT * FROM persons GROUP BY lastName, firstName;

두 사람이 같은 성을 가지고 있고 lastName으로 만 그룹화하면 그 사람 중 하나가 결과에서 생략됩니다. 이러한 사항을 고려해야합니다. 도움이 되었기를 바랍니다.


답변

SELECT  c2.field1 ,
        field2
FROM    (SELECT DISTINCT
                field1
         FROM   dbo.TABLE AS C
        ) AS c1
        JOIN dbo.TABLE AS c2 ON c1.field1 = c2.field1


답변

정말 좋은 질문입니다. 나는 이미 유용한 답변을 읽었지만 더 정확한 설명을 추가 할 수 있습니다.

추가 정보를 쿼리하지 않는 한 GROUP BY 문으로 쿼리 결과 수를 줄이는 것은 쉽습니다. 다음 테이블 ‘locations’가 있다고 가정 해 봅시다.

--country-- --city--
 France      Lyon
 Poland      Krakow
 France      Paris
 France      Marseille
 Italy       Milano

이제 쿼리

SELECT country FROM locations
GROUP BY country

결과 :

--country--
 France
 Poland
 Italy

그러나 다음 쿼리

SELECT country, city FROM locations
GROUP BY country

“프랑스”의 오른쪽에있는 필드에서 읽고 싶은 프랑스 도시 “리옹”, “파리”또는 “마르세유”중 어느 것을 컴퓨터가 어떻게 알 수 있기 때문에 MS SQL에서 오류가 발생합니까?

두 번째 쿼리를 수정하려면이 정보를 추가해야합니다. 이를 수행하는 한 가지 방법은 MAX () 또는 MIN () 함수를 사용하여 모든 후보 중에서 가장 큰 값 또는 가장 작은 값을 선택하는 것입니다. MAX () 및 MIN ()은 숫자 값에만 적용 할 수있을뿐 아니라 알파벳 순서의 문자열 값을 비교합니다.

SELECT country, MAX(city) FROM locations
GROUP BY country

결과 :

--country-- --city--
 France      Paris
 Poland      Krakow
 Italy       Milano

또는:

SELECT country, MIN(city) FROM locations
GROUP BY country

결과 :

--country-- --city--
 France      Lyon
 Poland      Krakow
 Italy       Milano

알파벳 (또는 숫자) 순서의 양쪽 끝에서 값을 선택하는 것이 좋으면 이러한 기능은 좋은 솔루션입니다. 그러나 이것이 사실이 아닌 경우 어떻게해야합니까? 예를 들어 문자 ‘M’으로 시작하는 특정 특성의 값이 필요하다고 가정합니다. 이제 상황이 복잡해집니다.

지금까지 내가 찾은 유일한 해결책은 전체 쿼리를 하위 쿼리에 넣고 외부에서 추가 열을 직접 작성하는 것입니다.

SELECT
     countrylist.*,
     (SELECT TOP 1 city
     FROM locations
     WHERE
          country = countrylist.country
          AND city like 'M%'
     )
FROM
(SELECT country FROM locations
GROUP BY country) countrylist

결과 :

--country-- --city--
 France      Marseille
 Poland      NULL
 Italy       Milano


답변

@aryaxt의 훌륭한 질문-5 년 전에 요청했기 때문에 큰 질문이라고 말할 수 있으며 오늘 답변을 찾으려고 노력했습니다.

나는 이것을 포함하기 위해 허용 된 답변을 편집하려고 시도했지만 내 편집으로 그것을 만들지 않는 경우 :

테이블이 크지 않고 기본 키가 자동 증가 정수라고 가정하면 다음과 같이 할 수 있습니다.

SELECT
  table.*
FROM table
--be able to take out dupes later
LEFT JOIN (
  SELECT field, MAX(id) as id
  FROM table
  GROUP BY field
) as noDupes on noDupes.id = table.id
WHERE
  //this will result in only the last instance being seen
  noDupes.id is not NULL


답변

시험

SELECT table.* FROM table
WHERE otherField = 'otherValue'
GROUP BY table.fieldWantedToBeDistinct
limit x