[sql] 하나의 열에 대해서만 DISTINCT

다음과 같은 쿼리가 있다고 가정 해 봅시다.

SELECT ID, Email, ProductName, ProductModel FROM Products

중복 이메일을 반환하지 않도록 수정하려면 어떻게해야합니까?

즉, 여러 행에 동일한 전자 메일이 포함 된 경우 결과에 해당 행 중 하나만 (바람직하게는 마지막 행) 만 포함 시키려고합니다. 다른 열에는 중복이 허용되어야합니다.

절 은 전체 행에서 좋아 DISTINCT하고 GROUP BY작동하는 것으로 보입니다. 그래서 어떻게 접근 해야할지 모르겠습니다.



답변

SQL Server 2005 이상을 사용하는 경우 다음을 사용하십시오.

SELECT *
  FROM (
                SELECT  ID,
                        Email,
                        ProductName,
                        ProductModel,
                        ROW_NUMBER() OVER(PARTITION BY Email ORDER BY ID DESC) rn
                    FROM Products
              ) a
WHERE rn = 1

편집 : where 절을 사용하는 예 :

SELECT *
  FROM (
                SELECT  ID,
                        Email,
                        ProductName,
                        ProductModel,
                        ROW_NUMBER() OVER(PARTITION BY Email ORDER BY ID DESC) rn
                    FROM Products
                   WHERE ProductModel = 2
                     AND ProductName LIKE 'CYBER%'

              ) a
WHERE rn = 1


답변

이것은 SQL Server 2005+를 가정하고 “마지막”에 대한 정의는 주어진 전자 메일의 최대 PK입니다

WITH CTE AS
(
SELECT ID,
       Email,
       ProductName,
       ProductModel,
       ROW_NUMBER() OVER (PARTITION BY Email ORDER BY ID DESC) AS RowNumber
FROM   Products
)
SELECT ID,
       Email,
       ProductName,
       ProductModel
FROM CTE
WHERE RowNumber = 1


답변

사용할 때 DISTINCT열이 아닌 별도의 행으로 생각하십시오. 열이 정확히 일치하지 않는 행만 반환합니다.

SELECT DISTINCT ID, Email, ProductName, ProductModel
FROM Products

----------------------
1 | something@something.com | ProductName1 | ProductModel1
2 | something@something.com | ProductName1 | ProductModel1

쿼리는 두 행을 모두 반환하므로 ID열이 다르기 . 열이 증가 ID하는 IDENTITY열 이라고 가정 하고 마지막을 반환하려면 다음과 같이 권장합니다.

SELECT DISTINCT TOP 1 ID, Email, ProductName, ProductModel
FROM Products
ORDER BY ID DESC

TOP 1순서대로 정렬하여 첫 번째 레코드 만 반환합니다.ID 먼저 마지막 행으로 결과를 반환합니다 내림차순. 이것은 당신에게 마지막 기록을 줄 것입니다.


답변

GROUP BY 기능을 사용하여이를 극복 할 수 있습니다

SELECT ID, Email, ProductName, ProductModel FROM Products GROUP BY Email


답변

Access의 경우 여기에 표시된 SQL Select 쿼리를 사용할 수 있습니다.

예를 들어이 테이블이 있습니다.

클라이언트 || NOMBRES || 우편

888 || T800 아놀드 || t800.arnold@cyberdyne.com

123 || 존 코너 || s.connor@skynet.com

125 || SARAH CONNOR ||s.connor@skynet.com

그리고 다른 메일 만 선택해야합니다. 당신은 이것을 할 수 있습니다 :

SQL 선택 :

SELECT MAX(p.CLIENTE) AS ID_CLIENTE
, (SELECT TOP 1 x.NOMBRES
    FROM Rep_Pre_Ene_MUESTRA AS x
    WHERE x.MAIL=p.MAIL
     AND x.CLIENTE=(SELECT MAX(l.CLIENTE) FROM Rep_Pre_Ene_MUESTRA AS l WHERE x.MAIL=l.MAIL)) AS NOMBRE,
p.MAIL
FROM Rep_Pre_Ene_MUESTRA AS p
GROUP BY p.MAIL;

이를 사용하여 최대 ID를 선택하고 해당 최대 ID에 해당하는 이름을 선택하면 다른 속성을 추가 할 수 있습니다. 그런 다음 끝에 고유 열을 필터링하고 마지막 고유 열로만 그룹화합니다.

이렇게하면 해당 데이터가 포함 된 최대 ID가 표시되며 min 또는 다른 함수를 사용할 수 있으며 해당 함수를 하위 쿼리에 복제 할 수 있습니다.

이 선택은 다음을 반환합니다 :

클라이언트 || NOMBRES || 우편

888 || T800 아놀드 || t800.arnold@cyberdyne.com

125 || SARAH CONNOR ||s.connor@skynet.com

선택한 열을 인덱싱해야하며 고유 열에는 모두 대문자 나 소문자로 숫자 데이터가 없어야합니다. 그렇지 않으면 작동하지 않습니다. 이것은 하나의 등록 된 메일에서만 작동합니다. 행복한 코딩 !!!


답변

이유 DISTINCTGROUP BY전체 행에 작업은 쿼리가 전체 행을 반환하기 때문입니다.

이해하기 쉽도록 : 쿼리가 리턴해야하는 내용을 손으로 작성해보십시오. 중복되지 않은 열에 넣을 내용이 모호하다는 것을 알 수 있습니다.

문자 그대로 다른 열의 내용을 신경 쓰지 않으면 반환하지 마십시오. 각 이메일 주소에 대해 임의의 행을 반환하면 약간 쓸모없는 것 같습니다.


답변

이 시도

;With Tab AS (SELECT DISTINCT Email FROM  Products)
SELECT Email,ROW_NUMBER() OVER(ORDER BY Email ASC) AS  Id FROM Tab
ORDER BY Email ASC