여러 열에 걸쳐 중복되는 항목을 찾으려면 어떻게 해야 합니까?
다음 SQL 코드와 같은 작업을 수행하려고 합니다.
select s.id, s.name,s.city
from stuff s
group by s.name having count(where city and name are identical) > 1
다음을 작성하려면(단, 이름만 일치하거나 시만 일치할 경우에는 무시해야 합니다.)
id name city
904834 jim London
904835 jim London
90145 Fred Paris
90132 Fred Paris
90133 Fred Paris
중복id
쌍으로name
그리고.city
:
select s.id, t.*
from [stuff] s
join (
select name, city, count(*) as qty
from [stuff]
group by name, city
having count(*) > 1
) t on s.name = t.name and s.city = t.city
SELECT name, city, count(*) as qty
FROM stuff
GROUP BY name, city HAVING count(*)> 1
이런 게 효과가 있을 거예요.성능에 대해서는 모르니까 테스트를 해 보세요.
select
id, name, city
from
[stuff] s
where
1 < (select count(*) from [stuff] i where i.city = s.city and i.name = s.name)
사용.count(*) over(partition by...)
는 불필요한 반복을 찾기 위한 간단하고 효율적인 방법을 제공하며 영향을 받는 모든 행과 원하는 열을 나열합니다.
SELECT
t.*
FROM (
SELECT
s.*
, COUNT(*) OVER (PARTITION BY s.name, s.city) AS qty
FROM stuff s
) t
WHERE t.qty > 1
ORDER BY t.name, t.city
최신 RDBMS 버전에서는count(*) over(partition by...)
MySQL V 8.0에는 아래와 같은 "윈도 기능"이 도입되었습니다(MySQL 8.0).
CREATE TABLE stuff( id INTEGER NOT NULL ,name VARCHAR(60) NOT NULL ,city VARCHAR(60) NOT NULL );
INSERT INTO stuff(id,name,city) VALUES (904834,'jim','London') , (904835,'jim','London') , (90145,'Fred','Paris') , (90132,'Fred','Paris') , (90133,'Fred','Paris') , (923457,'Barney','New York') # not expected in result ;
SELECT t.* FROM ( SELECT s.* , COUNT(*) OVER (PARTITION BY s.name, s.city) AS qty FROM stuff s ) t WHERE t.qty > 1 ORDER BY t.name, t.city
id | name | city |qty-----: | :--- | :----- | --:90145 | Fred | Paris |90132 | Fred | Paris | 390133 | Fred | Paris | 3904834 | jim | 런던 | 2904835 | jim | 런던 | 2
db <>여기에 추가
창 기능MySQL은 쿼리의 각 행에 대해 해당 행과 관련된 행을 사용하여 계산을 수행하는 창 함수를 지원합니다.여기에는 RANK(), LAG() 및 NTILLE() 등의 함수가 포함됩니다.또, SUM()이나 AVG()등의 기존의 집약 함수를 창 함수로 사용할 수 있게 되었습니다.자세한 내용은 섹션 12.21 "창 기능"을 참조하십시오.
이 방법은 매우 유연하고 효율적이라는 것을 알았습니다.
select
s1.id
,s1.name
,s1.city
from
stuff s1
,stuff s2
Where
s1.id <> s2.id
and s1.name = s2.name
and s1.city = s2.city
SELECT Feild1, Feild2, COUNT(*)
FROM table name
GROUP BY Feild1, Feild2
HAVING COUNT(*)>1
이것으로 모든 답을 얻을 수 있습니다.
직접 가입해서 이름과 도시를 일치시켜야 합니다.그리고 카운트별로 그룹화.
select
s.id, s.name, s.city
from stuff s join stuff p ON (
s.name = p.city OR s.city = p.name
)
group by s.name having count(s.name) > 1
OP 질문에서 OP는 열을 그룹화하고 열을 그룹화하지 않는 추가 열을 얻으려고 합니다.
그래서 규칙적인group by
+having
작동하지 않을 수 있습니다.
나는 사용할 것이다.EXISTS
에 대한 서브쿼리.HAVING
.
서브쿼리에 중복으로 표시할 열을 추가할 수 있습니다.
SELECT s.id, s.name,s.city
FROM stuff s
WHERE EXISTS (
SELECT 1
FROM stuff ss
WHERE
s.name = ss.name
AND
s.city = ss.city
GROUP BY ss.name,ss.city
HAVING COUNT(*) > 1
)
적절한 인덱스를 작성하면, 보다 뛰어난 퍼포먼스를 얻을 수 있습니다.join
CREATE INDEX IX_name ON stuff (
name,
city
);
또 다른 방법으로COUNT
필터 조건을 사용하여 그룹화 열을 추가하는 창 기능PARTITION BY
일부
SELECT s.id, s.name,s.city
FROM (
SELECT *,COUNT(*) OVER(PARTITION BY name,city) cnt
FROM stuff
) s
WHERE cnt > 1
다음을 사용하여 필요한 출력을 달성하는 다른 방법을 추가할 수 있습니다.Cross Apply
다음과 같이 입력합니다.
select s.* from stuff s
cross apply(
select name, city from stuff
group by name, city
having Count(*) > 1) x
where s.name = x.name and s.city=x.city
70개의 열이 있고 4개만 중복되는 스테이징 테이블을 지정하면 이 코드는 문제를 일으키는 열을 반환합니다.
SELECT
COUNT(*)
,LTRIM(RTRIM(S.TransactionDate))
,LTRIM(RTRIM(S.TransactionTime))
,LTRIM(RTRIM(S.TransactionTicketNumber))
,LTRIM(RTRIM(GrossCost))
FROM Staging.dbo.Stage S
GROUP BY
LTRIM(RTRIM(S.TransactionDate))
,LTRIM(RTRIM(S.TransactionTime))
,LTRIM(RTRIM(S.TransactionTicketNumber))
,LTRIM(RTRIM(GrossCost))
HAVING COUNT(*) > 1
.
언급URL : https://stackoverflow.com/questions/8149210/how-do-i-find-duplicates-across-multiple-columns
'programing' 카테고리의 다른 글
각 GROUP BY 그룹에서 첫 번째 행을 선택하시겠습니까? (0) | 2023.04.11 |
---|---|
여러 줄의 bash 코드를 단말기에 붙여넣고 한 번에 실행하려면 어떻게 해야 하나요? (0) | 2023.04.11 |
데이터베이스 다이어그램 지원 개체를 설치할 수 없습니다...유효한 소유자가 없습니다. (0) | 2023.04.11 |
지정된 값을 포함하는 열의 VBA 셀 수 (0) | 2023.04.11 |
다른 블록을 시작하기 전에 두 개의 비동기 블록이 실행될 때까지 기다리는 중 (0) | 2023.04.11 |