2011-02-03 4 views
9

그것은, 여기 내 쿼리 아마 간단 것 :제거 중복 (그냥 "별개의 사용"하지 않음)

SELECT DISTINCT U.NAME, P.PIC_ID 
FROM USERS U, PICTURES P, POSTINGS P1 
WHERE U.EMAIL_ID = P1.EMAIL_ID AND P1.PIC_ID = P.PIC_ID AND P.CAPTION LIKE '%car%'; 

하지만 행이 같은 u.name 모두를 가지고있는 곳은 중복을 제거합니다 p.pic_id. 이름의 중복이 있으면 다른 행을 제외하기를 원합니다. 이상한 쿼리이지만, 일반적으로 SELECT 절의 단일 열에 어떻게 distinct를 적용 할 수 있습니까?

+1

하나의 U.NAME에서 여러 개의 P.PIC_ID 중 원하는 것을 선택 하시겠습니까? –

답변

15

임의로 최소 PIC_ID를 유지하도록 선택합니다. 또한 암시 적 조인 구문을 사용하지 마십시오. 내가 제대로 이해하면

SELECT U.NAME, MIN(P.PIC_ID) 
    FROM USERS U 
     INNER JOIN POSTINGS P1 
      ON U.EMAIL_ID = P1.EMAIL_ID 
     INNER JOIN PICTURES P 
      ON P1.PIC_ID = P.PIC_ID 
    WHERE P.CAPTION LIKE '%car%' 
    GROUP BY U.NAME; 
+0

비즈니스 케이스에 따라 MIN 또는 MAX를 사용할 수 있습니다 (동시에 두 가지를 동시에 사용할 수 없음). – Naufal

1

MIN 또는 MAX과 같은 다른 열에 대해서는 어떤 값을 선택해야하는지 쿼리에 알릴 필요가 있습니다.

SELECT 
    U.NAME, MIN(P.PIC_ID) 
FROM 
    USERS U, 
    PICTURES P, 
    POSTINGS P1 
WHERE 
    U.EMAIL_ID = P1.EMAIL_ID AND 
    P1.PIC_ID = P.PIC_ID AND 
    P.CAPTION LIKE '%car%' 
GROUP BY 
    U.NAME; 
+1

나는 이것이 그가 원하는 것이라고 생각하지 않는다. 나는 그가 모든 그림을 원한다고 생각한다. 그러나 한 명의 사용자가 여러 장의 그림을 가지고있는 경우에는 목록에서 반복되는 사용자 이름을 원하지 않는다. – KeithS

+1

묵시적 조인 구문을 사용하지 마십시오. 당신이 그에게 어떻게 일을 하는지를 보여주고 있다면, 올바르게 행동하는 법을 보여주십시오. – HLGEM

+0

@HLGEM, 내 자신의 지식으로, 묵시적 구문에 무엇이 잘못 되었습니까? tigerlogic의 D3과 같은 일부 ODBC 드라이버는 암시 적 구문 만 지원합니다. –

0

, 당신은 같은 이름 (및 다른 IDS) 등의 이름이 한 번 테이블에 이상 발생하는 모든 사진의 목록을합니다. 나는이 트릭을 할 것입니다 생각 : 나는 그것을 실행하지 않은

SELECT U.NAME, P.PIC_ID 
FROM USERS U, PICTURES P, POSTINGS P1 
WHERE U.EMAIL_ID = P1.EMAIL_ID AND P1.PIC_ID = P.PIC_ID AND U.Name IN (
SELECT U.Name 
FROM USERS U, PICTURES P, POSTINGS P1 
WHERE U.EMAIL_ID = P1.EMAIL_ID AND P1.PIC_ID = P.PIC_ID AND P.CAPTION LIKE '%car%'; 
GROUP BY U.Name HAVING COUNT(U.Name) > 1) 

, 그래서 구문 오류가 한두있을 수 있습니다. 내가 제대로 이해하면

+1

묵시적 조인 구문을 사용하지 마십시오. 당신이 그에게 어떻게 일을 하는지를 보여주고 있다면, 올바르게 행동하는 법을 보여주십시오. – HLGEM

+0

나는 그것을 고려했다. 그러나 나는 그가 연구하고 있던 문제 만 풀고 싶었다. –

1

, 당신은 하나 개의 컬럼에 중복을 제외 나열 할, 내부는 가지 혼란 하위 선택

select u.* [whatever joined values] 
from users u 
inner join 
(select name from users group by name having count(*)=1) uniquenames 
on uniquenames.name = u.name 
2

귀하의 질문에 가입; 사용자 당 하나의 행만 보시겠습니까, 아니면 그림 하나당 행을 표시하고 U.NAME 필드에서 반복되는 값을 표시하지 않으시겠습니까? 나는 네가 두 번째를 원한다고 생각한다. 그렇지 않다면 첫 번째 질문에 대한 답이 많습니다.

반복 값을 표시할지 여부는 SQL이 실제로 설계되지 않은 표시 논리입니다. 루프에서 커서를 사용하여 결과를 행 단위로 처리 할 수 ​​있지만 많은 성능이 저하됩니다. .NET 언어 나 Java와 같은 "현명한"프론트 엔드 언어를 사용하는 경우이 데이터를 넣은 구성을 값 비싼 방식으로 조작하여 반복되는 값을 표시하지 않도록 한 다음 UI에 마지막으로 표시합니다.

Microsoft SQL Server를 사용하고 있고 변환이 데이터 계층에서 수행되어야하는 경우 CTE (Computed Table Expression)를 사용하여 초기 쿼리를 보유한 다음 해당 테이블의 각 행에서 값을 선택하는 것이 좋습니다. CTE는 이전 행의 열이 동일한 데이터를 보유하는지 여부를 기반으로합니다. 그것은 커서보다 성능이 좋지만 다소간 지저분 할 것입니다. 관찰 :

USING CTE (Row, Name, PicID) 
AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY U.NAME, P.PIC_ID), 
     U.NAME, P.PIC_ID 
    FROM USERS U 
     INNER JOIN POSTINGS P1 
      ON U.EMAIL_ID = P1.EMAIL_ID 
     INNER JOIN PICTURES P 
      ON P1.PIC_ID = P.PIC_ID 
    WHERE P.CAPTION LIKE '%car%' 
    ORDER BY U.NAME, P.PIC_ID 
) 
SELECT 
    CASE WHEN current.Name == previous.Name THEN '' ELSE current.Name END, 
    current.PicID 
FROM CTE current 
LEFT OUTER JOIN CTE previous 
    ON current.Row = previous.Row + 1 
ORDER BY current.Row 

위의 샘플은 TSQL에 특정한 것입니다. PL/SQL과 같은 다른 DBPL에서 작동한다는 보장은 없지만 엔터프라이즈 급 SQL 엔진의 대부분은 비슷한 점이 있다고 생각합니다.