여러 열에서 DISTINCT를 선택하려면 어떻게 해야 합니까?
나는 두 개의 열을 합친 것이 모두 다른 테이블에서 모든 행을 검색해야 합니다.그래서 나는 같은 날에 발생한 다른 판매가 없는 모든 판매를 같은 가격으로 원합니다.날짜와 가격을 기준으로 고유한 판매가 활성 상태로 업데이트됩니다.
그래서 내 생각은:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
하지만 그보다 더 멀리 가면 제 뇌가 아파요.
SELECT DISTINCT a,b,c FROM t
대략 다음과 같습니다.
SELECT a,b,c FROM t GROUP BY a,b,c
GROUP BY 구문이 더 강력하므로 이 구문에 익숙해지는 것이 좋습니다.
문의 사항은 다음과 같습니다.
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
)
지금까지의 답변을 종합하여 정리하고 개선하면 다음과 같은 우수한 질문에 도달할 수 있습니다.
UPDATE sales
SET status = 'ACTIVE'
WHERE (saleprice, saledate) IN (
SELECT saleprice, saledate
FROM sales
GROUP BY saleprice, saledate
HAVING count(*) = 1
);
둘 중 어느 쪽보다 훨씬 빠른 속도입니다.(Postgre에 대한 내 테스트에서) 요인 10 - 15에 의해 현재 승인된 답변의 성능을핵화합니다.SQL 8.4 및 9.1).
그러나 이것은 여전히 최적의 상태와는 거리가 멉니다.더 나은 성능을 위해 (안티) 세미 조인을 사용합니다. EXISTS
표준 이 SQL 이후).SQL 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<>여기로 이동
올드 sqlifiddle
행을 식별하는 고유 키
키가(테이블에대기키또고없키경가는우유는본한▁for경▁if우없)id
열을 시스템 열로 할 수 .ctid
이 쿼리의 목적(다른 목적은 아님):
AND s1.ctid <> s.ctid
모든 테이블에는 기본 키가 있어야 합니다.아직 없으면 하나 더 추가합니다.나는 제안합니다.serial
는또.IDENTITY
Postgres 10+의열다니입.
관련:
이게 어떻게 더 빨라요?
의 하위 EXISTS
안티스파이웨어는 첫 번째 속임수가 발견되는 즉시 평가를 중지할 수 있습니다(자세히 살펴봐야 할 의미가 없음).중복 항목이 거의 없는 기본 테이블의 경우 이 방법이 약간 더 효율적일 뿐입니다.중복 데이터가 많으면 효율성이 훨씬 높아집니다.
빈 업데이트 제외
이있는행경이 status = 'ACTIVE'
이 업데이트는 아무것도 변경하지 않지만 새 행 버전을 전체 비용으로 삽입합니다(예외 사항이 적용됨).일반적으로, 당신은 이것을 원하지 않습니다. 다항목추를 합니다.WHERE
위에서 설명한 것과 같은 조건을 사용하여 이를 방지하고 속도를 더욱 높일 수 있습니다.
한다면status
는 정의됩니다.NOT NULL
다음과 같이 단순화할 수 있습니다.
AND status <> 'ACTIVE';
은 열데이다지합원니다야해를 해야 합니다.<>
교환입니다.다음과 같은 유형json
하지 마. 참조:
NULL 처리에서 미묘한 차이가 있음
이 쿼리는 (조엘이 현재 수락한 답변과 달리) NULL 값을 동일하게 처리하지 않습니다.다음 두 행:(saleprice, saledate)
(사람의 눈과 동일하게 보이지만) "눈"의 자격이 있습니다.
(123, NULL)
(123, NULL)
또한 NULL 값이 SQL 표준에 따라 동일하게 비교되지 않기 때문에 고유 인덱스와 거의 모든 위치에 전달됩니다.참조:
OTOH,GROUP BY
,DISTINCT
또는DISTINCT ON ()
NULL 값을 동일하게 처리합니다.원하는 항목에 따라 적절한 쿼리 스타일을 사용합니다.이 더 빠른 쿼리를 다음과 같이 사용할 수 있습니다.=
NULL 비교를 동일하게 하기 위해 일부 또는 모든 비교를 수행합니다. 정보
열이 NOT NULL
이견의 여지가 없습니다.
쿼리의 문제는 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를 사용할 수도 있습니다. 일치하는 행이 하나만 있는 경우 열 값을 반환하는 함수만 사용하는 것이 중요합니다.
DBMS가 다음과 같은 여러 열로 구분할 수 없는 경우:
select distinct(col1, col2) from table
일반적으로 다중 선택은 다음과 같이 안전하게 실행할 수 있습니다.
select distinct * from (select col1, col2 from table ) as x
이것은 대부분의 DBMS에서 작동할 수 있기 때문에 그룹화 기능을 사용하지 않기 때문에 솔루션별 그룹화보다 빠를 것으로 예상됩니다.
하나의 열 'GrandOfLucht'에서 고유한 값을 선택하고 싶지만 'sorting' 열에 지정된 순서대로 정렬되어야 합니다.다음을 사용하여 한 열의 고유한 값을 가져올 수 없습니다.
Select distinct GrondOfLucht,sortering
from CorWijzeVanAanleg
order by sortering
또한 'Sortering' 열에 'GrandOfLucht' 및 'Sortering'이 고유하지 않기 때문에 결과는 모든 행이 됩니다.
GROUP을 사용하여 'GrandOfLucht'의 레코드를 정렬 순서대로 선택합니다.
SELECT GrondOfLucht
FROM dbo.CorWijzeVanAanleg
GROUP BY GrondOfLucht, sortering
ORDER BY MIN(sortering)
언급URL : https://stackoverflow.com/questions/54418/how-do-i-or-can-i-select-distinct-on-multiple-columns
'sourcecode' 카테고리의 다른 글
시작 화면 스토리보드가 이미지를 표시하지 않음 (0) | 2023.05.08 |
---|---|
SDK iOS 8.0의 제품 유형 Unit Test Bundle에 대한 코드 서명 필요 (0) | 2023.05.08 |
Vb를 사용하여 프로세스를 종료하려면 어떻게 해야 합니까?NET 또는 C#? (0) | 2023.05.08 |
각도 CLI 오류:serve 명령을 Angular 프로젝트에서 실행해야 하지만 프로젝트 정의를 찾을 수 없습니다. (0) | 2023.05.08 |
'로컬 시스템' 계정과 '네트워크 서비스' 계정의 차이점은 무엇입니까? (0) | 2023.05.08 |