복붙노트

[SQL] 어떻게 (또는 내가 수 있습니다) 여러 열에서 DISTINCT 선택합니까?

SQL

어떻게 (또는 내가 수 있습니다) 여러 열에서 DISTINCT 선택합니까?

나는 결합 된 2 열은 모든 다른 테이블에서 모든 행을 검색 할 필요가있다. 나도 같은 가격에 같은 날에 일어난 다른 판매되지 않은 모든 판매를 원하는 그래서. 날짜와 가격에 따라 고유 한 판매는 활성 상태로 업데이트받을 것입니다.

내가 생각 해요 그래서 :

UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
             FROM sales
             HAVING count = 1)

하지만 내 뇌는 더 멀리보다가는 아파요.

해결법

  1. ==============================

    1.

    SELECT DISTINCT a,b,c FROM t
    

    거의 비슷하다 :

    SELECT a,b,c FROM t GROUP BY a,b,c
    

    더 강력으로는, 구문에 의해 GROUP에 익숙해 좋은 아이디어입니다.

    쿼리의 경우,이 같은 그것을 할 것입니다 :

    UPDATE sales
    SET status='ACTIVE'
    WHERE id IN
    (
        SELECT id
        FROM sales S
        INNER JOIN
        (
            SELECT saleprice, saledate
            FROM sales
            GROUP BY saleprice, saledate
            HAVING COUNT(*) = 1 
        ) T
        ON S.saleprice=T.saleprice AND s.saledate=T.saledate
     )
    
  2. ==============================

    2.지금까지 함께 답변을 넣을 경우이 뛰어난 쿼리에 도착하는 것, 정리 및 개선 :

    지금까지 함께 답변을 넣을 경우이 뛰어난 쿼리에 도착하는 것, 정리 및 개선 :

    UPDATE sales
    SET    status = 'ACTIVE'
    WHERE  (saleprice, saledate) IN (
        SELECT saleprice, saledate
        FROM   sales
        GROUP  BY saleprice, saledate
        HAVING count(*) = 1 
        );
    

    어느 훨씬 더 빨리 둘 중 하나보다. 핵무기 요소 (10)에 의해 현재 허용 대답의 성능 - 15 (내 테스트에서 PostgreSQL의 8.4 및 9.1).

    하지만이 최적의에서 멀리 아직도있다. 사용하십시오 NOT EXISTS (반) 더 나은 성능을 위해 반 가입 할 수 있습니다. 표준 SQL, 영원히 주변에있다 (적어도 PostgreSQL의 7.2 이후, 오랫동안이 질문에 질문하기 전에)과 맞는 제시된 요구 사항을 완벽하게되어 존재합니다

    UPDATE sales s
    SET    status = 'ACTIVE'
    WHERE  NOT EXISTS (
       SELECT FROM sales s1                     -- SELECT list can be empty for EXISTS
       WHERE  s.saleprice = s1.saleprice
       AND    s.saledate  = s1.saledate
       AND    s.id <> s1.id                     -- except for row itself
       )
    AND    s.status IS DISTINCT FROM 'ACTIVE';  -- avoid empty updates. see below
    

    DB <> 바이올린 여기 올드 SQL 바이올린

    당신이 테이블 (예제에서는 ID)에 대한 기본 또는 고유 키가없는 경우,이 쿼리의 목적을 위해 시스템 열 CTID로 대체 (하지만 다른 목적으로) 할 수 있습니다 :

       AND    s1.ctid <> s.ctid
    

    모든 테이블에 기본 키가 있어야합니다. 아직 하나를 가지고 있지 않은 경우 하나를 추가합니다. 나는 직렬 또는 포스트 그레스 10 +의 IDENTITY 열을 제안한다.

    관련 :

    의 하위 쿼리가있는 안티 - 세미에 처음으로 참여할 속는 사람이 (더 찾고 더 포인트를) 발견되는 즉시 평가를 중지 할 수 있습니다. 몇 중복으로 기본 테이블이 단지 약간 더 효율적입니다. 중복이 많은이 방법이 더 효율적이된다.

    이미 상태가 행의 경우 = 'ACTIVE'이 업데이트는 아무것도 변하지 않을 것입니다,하지만 여전히 전체 비용으로 새로운 행 버전 삽입 (약간의 예외 적용). 일반적으로, 당신이 원하지 않는다. 위의 증명과 같은 조건이이 문제를 방지하기 위해 WHERE 다른를 추가하고도 빠르게합니다

    상태가 NOT NULL을 정의되어있는 경우, 당신은 할 수 단순화 할 수 있습니다 :

    AND status <> 'ACTIVE';
    

    (조엘에 의해 현재 허용 대답과는 달리)이 쿼리는 동일로하지 치료 NULL 값을한다. (saleprice, saledate)에 대한 다음 두 행은 "독특한"로 자격이 (인간의 눈과 동일한 찾고 있지만) :

    (123, NULL)
    (123, NULL)
    

    NULL 값은 SQL 표준에 동일한있어서, 비교하지 않기 때문에 또한, 고유 인덱스에 전달하고 거의 다른 곳. 보다:

    OTOH, GROUP BY, DISTINCT 또는 DISTINCT ON ()로 처리 된 동일한 NULL 값. 당신이 달성하려는 작업에 따라 적절한 쿼리 스타일을 사용합니다. 당신은 여전히 ​​대신 NULL 동등 비교하기에 일부 또는 전체 비교를 위해 =의 구별을지지 않습니다와 함께이 빠르게 쿼리를 사용할 수 있습니다. 더:

    모든 열을 NOT NULL 정의 비교되는 경우, 이견의 여지가 없다.

  3. ==============================

    3.쿼리에 대한 문제는 (당신이 본질적으로 별개의 사용에 의해 수행) GROUP BY 절을 사용할 때 해당 그룹화하거나 집계 함수 열을 사용할 수 있다는 것입니다. 잠재적으로 다른 값이 있기 때문에 당신은 열 ID를 사용할 수 없습니다. 귀하의 경우가 있기 때문에 HAVING 절의 항상 한 값이지만, 대부분의 RDBMS는 그것을 인식 할만큼 똑똑하지 않다.

    쿼리에 대한 문제는 (당신이 본질적으로 별개의 사용에 의해 수행) GROUP BY 절을 사용할 때 해당 그룹화하거나 집계 함수 열을 사용할 수 있다는 것입니다. 잠재적으로 다른 값이 있기 때문에 당신은 열 ID를 사용할 수 없습니다. 귀하의 경우가 있기 때문에 HAVING 절의 항상 한 값이지만, 대부분의 RDBMS는 그것을 인식 할만큼 똑똑하지 않다.

    그러나 이것은 작동합니다 (그리고 가입이 필요하지 않습니다)

    UPDATE sales
    SET status='ACTIVE'
    WHERE id IN (
      SELECT MIN(id) FROM sales
      GROUP BY saleprice, saledate
      HAVING COUNT(id) = 1
    )
    

    또한이 기능을 사용하는 경우에만 중요하다, MIN 대신 MAX 또는 AVG를 사용할 수있는 반환 하나 개 일치하는 행이있는 경우 열 값.

  4. ==============================

    4.나는 하나의 열 'GrondOfLucht'에서 고유 한 값을 선택합니다 그러나 그들은 'sortering'컬럼에 주어진 순서대로 정렬한다. 내가 사용하는 하나의 컬럼의 고유 값을받을 수 없습니다

    나는 하나의 열 'GrondOfLucht'에서 고유 한 값을 선택합니다 그러나 그들은 'sortering'컬럼에 주어진 순서대로 정렬한다. 내가 사용하는 하나의 컬럼의 고유 값을받을 수 없습니다

    Select distinct GrondOfLucht,sortering
    from CorWijzeVanAanleg
    order by sortering
    

    또한 열 'sortering'를 줄 것이다 'GrondOfLucht'AND 'sortering이'고유하지 않기 때문에, 결과는 모든 행됩니다.

    sortering '에 의해 주어진 위해'GrondOfLucht '의 레코드를 선택하기 위해 그룹을 사용

    SELECT        GrondOfLucht
    FROM            dbo.CorWijzeVanAanleg
    GROUP BY GrondOfLucht, sortering
    ORDER BY MIN(sortering)
    
  5. ==============================

    5.당신의 DBMS 이런 여러 열이 별개 지원하지 않는 경우 :

    당신의 DBMS 이런 여러 열이 별개 지원하지 않는 경우 :

    select distinct(col1, col2) from table
    

    다음과 같이 멀티 안전하게 실행할 수 있습니다 일반적으로 선택 :

    select distinct * from (select col1, col2 from table ) as x
    

    이것은 DBMS의 대부분의 작업을 할 수 있으며 이것은 당신이 그룹화 기능을 피하고으로 솔루션이 빠른 군에 비해 될 것으로 예상됨에.

  6. from https://stackoverflow.com/questions/54418/how-do-i-or-can-i-select-distinct-on-multiple-columns by cc-by-sa and MIT license