개발 꿀팁/PHP

mysql 두 테이블에서 중복되지 않는 데이터 가져오기

Jammie 2022. 7. 21. 17:18
반응형

일. 서언
예를 들어 표 구조가 같은 두 개의 데이터 테이블이 있는데, a표 데이터 300W 행과 b표 데이터 17W 행은 a표에 b표가 포함되지 않은 데이터를 얻어야 한다.다음은 취득과정을 대략적으로 기록하여 추억조회가 용이하도록 하겠습니다

a표 구조:
id
pay_id
user_id

표 b의 구조와 표 a의 구조는 항상 동일하지만 표 b의 user_id 필드는 모두 고유하고 표 a의 user_id 필드는 중복될 수 있다.

2.distinct를 사용하여 중복되지 않는 데이터를 가져옵니다.
Mysql은 중복을 배제하기 위한 키워드 distinct를 제공한다는 것을 우리 모두 알고 있습니다.

1. a표에서 중복되지 않는 데이터를 먼저 가져옵니다

select count(distinct user_id) from  a  where 1   ;
+-----------------------------+
| count(distinct user_id) |
+-----------------------------+
|                      240522 |
+-----------------------------+

2. b표 데이터 가져오기

mysql> select count(1) from b;
+----------+
| count(1) |
+----------+
|   176731 |

a표와 b표는 일정한 차이가 있고, 그 다음은 차분값을 구하는 필드이다.

3. 선별된 데이터 조회

SELECT distinct user_id FROM a LEFT JOIN b  ON a.user_id= b.user_id WHERE f.user_id IS NULL ';

+-------------+
| user_id |
+-------------+
|    10000058 |
|    10009228 |
|    10042967 |
....
+-------------+

조회 결과 중복되지 않은 user_id 값을 얻었지만 중복되지 않은 행 데이터를 요구했기 때문에 a표에서 pay_id 값을 얻어야 했다.다만 distinct를 통해 다른 데이터를 얻는 데 문제가 있었다.

4,distinct 여러 필드의 문제
(1) 산만하게 쓸 수 없다
예를 들어, distinctuser_id, distinctuser_id와 같은 쓰기 방법은 오류를 보고합니다.

(2) 올바른 distinct 작성법

 distinct  user_id, pay_id
SELECT distinct p.user_id,p.pay_id FROM a as p  LEFT JOIN b as f ON p.user_id = f.user_id 
WHERE f.user_id IS NULL  order by p.user_id asc limit 10;

비슷하다:
| user_id | pay_id |
+-------------+--------+
|    10000058 |     16 |
|    10000058 |     17 |
|    10000058 |     18 |
|    10000058 |     19 |
|    10000058 |     20 |

distinct 여러 개의 필드가 있는 경우, user_id와 pay_id가 동일한 데이터만 제외하며, user_id가 중복되는 부분만 제외하여 고유한 user_id와 대응하는 pay_id를 가져옵니다.

(3) 니즈에 맞는 표기법 (left join 사용)

SELECT  a.pay_id,a.user_id  FROM   a LEFT JOIN b  as f ON a.user_id = f.user_id 
where f.user_id IS NULL  GROUP BY a.user_id order by a.user_id desc limit 10; 

+----------+-------------+
| pay_id   |  |user_id |
+----------+-------------+
|       16 |     10000058 |
|       15 |    10009228 |
|       77 |    10042967 |
|      687 |     10043113 |
|      119 |    10043147 |

우리는 여기서 distinct 키워드를 사용하지 않습니다. 첫째, left join을 사용하여 두 표에서 중복되는 부분을 제거하고, 둘째, group by를 사용하여 가중치 특성을 제거하며, user_id로 그룹화할 때 자연스럽게 user_id도 결과에서 유일합니다.

이 편을 기록한 이유는 처음에 생각이 너무 복잡해서, 무슨 조회냐, not exist라든지, 스스로 문제를 어렵게 만들었는데, distinct를 사용해서 데이터를 얻는 것, 잘못된 방향으로 노력하는 것 등, 어쨌든 잘못된 것이다.하필이면 제일 많이 쓰는 lef를 까먹었어요조인과 그룹 by, 분명 sql 하나면 될 일이다

반응형