programing

여러 열에 걸쳐 중복되는 항목을 찾으려면 어떻게 해야 합니까?

abcjava 2023. 4. 11. 21:35
반응형

여러 열에 걸쳐 중복되는 항목을 찾으려면 어떻게 해야 합니까?

다음 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

반응형