여러 열에서 중복 항목을 찾으려면 어떻게합니까?


98

그래서 아래의 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

답변:


137

id쌍에 대해 복제 됨 namecity:

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

name또는 city포함 하는 경우 null외부 쿼리에서는보고되지 않지만 내부 쿼리에서는 일치됩니다.
Adam Parkin 2015 년

3
값이 가능하게 포함 할 경우 null당신이 그것을 변경해야 다음 (내가 부족하지 않는 무언가를) CROSS JOIN추가 한 후 (전체 직교 제품)과 WHERE같은 조항 :WHERE ((s.name = t.name) OR (s.name is null and t.name is null)) AND ((s.city = t.city) OR (s.city is null and t.city is null))
아담 파킨

56
 SELECT name, city, count(*) as qty 
 FROM stuff 
 GROUP BY name, city HAVING count(*)> 1

10

이와 같은 것이 트릭을 할 것입니다. 성능에 대해 모르기 때문에 몇 가지 테스트를 수행하십시오.

select
  id, name, city
from
  [stuff] s
where
1 < (select count(*) from [stuff] i where i.city = s.city and i.name = s.name)

6

를 사용하면 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
    아이디 | 이름 | 도시 | 수량
----- : | : --- | : ----- | -:
 90145 | 프레드 | 파리 | 삼
 90132 | 프레드 | 파리 | 삼
 90133 | 프레드 | 파리 | 삼
904834 | 짐 | 런던 | 2
904835 | 짐 | 런던 | 2

db <> 여기 바이올린

창 기능. MySQL은 이제 쿼리의 각 행에 대해 해당 행과 관련된 행을 사용하여 계산을 수행하는 창 함수를 지원합니다. 여기에는 RANK (), LAG () 및 NTILE ()과 같은 함수가 포함됩니다. 또한 여러 기존 집계 함수를 이제 창 함수로 사용할 수 있습니다. 예를 들어, SUM () 및 AVG (). 자세한 내용은 Section 12.21,“창 기능”을 참조하십시오 .


3

이 게시물에서 게임에 조금 늦었지만이 방법이 매우 유연하고 효율적이라는 것을 알았습니다.

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

2

스스로 물건에 가입하고 이름과 도시를 일치시켜야합니다. 그런 다음 개수별로 그룹화합니다.

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

SQL Server에서 실패 : 집계되지 않은 모든 열은 GROUP BY
gbn

0

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

.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.