SQL 중급_집합연산 UNION

Eunjung-Cho·2021년 7월 7일
0

SQL

목록 보기
10/16

집합연산 UNION

  • 두 테이블을 합칠때, 중복되어 있는 행이 있으면 그 중복값을 제외하고 합침
  • SELECT DISTINCT처럼 유니크한것만 보여준다고 생각하면된다.

UNION ALL

  • 두 테이블을 합칠때, 중복값 까지 다 합침

Full outer Join

  • mysql에서는 해당 함수가 지원이 안된다.

  • 그래서 LEFT JOIN UNION RIGHT JOIN으로 FULL OUTER JOIN을 한다.

해커랭크 문제:Symmetric Pairs

풀이1

  • 생각의 흐름:
  1. SELECT FROM 먼저 적기
SELECT X,Y
FROM Functions
  1. 조건 살피기:

    2-1. all such symmetric pairs in ascending order by the value of X

    SELECT X,Y
    FROM Functions
    ORDER BY X

    2-2. symmetric pairs: Two pairs (X1, Y1) and (X2, Y2) are said to be symmetric pairs if X1 = Y2 and X2 = Y1

    2-2-1. 테이블 1개에서 참조해야하므로 INNER JOIN 을 쓰고 합치는 조건을 문제에서 확인 후 ON뒤에 써준다.

    SELECT X,Y
    FROM Functions AS f1
    	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
    ORDER BY X

    2-2-2. 출력해야 될 테이블은 f1을 기준으로 합쳤으므로 SELECT문과 ORDER문의 컬럼을 f1의 컬럼으로 수정해준다.

    SELECT f1.X, f1.Y
    FROM Functions AS f1
    	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
    ORDER BY f1.X

    2-3. List the rows such that X1 ≤ Y1.

    SELECT f1.X, f1.Y
    FROM Functions AS f1
    	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
    WHERE f1.x <= f1.y
    ORDER BY f1.X
  2. 조건 빠진거 없나 확인하고 돌리기

  3. test로 돌린 것 보고 오류 확인
    4-1. 문제의 sample output에는 21 21 부분이 없었는데 여기서는 등장. 뭔가 output에 중복이 있는 느낌 -> GROUP BY

      SELECT f1.X, f1.Y
      FROM Functions AS f1
      	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
      WHERE f1.x <= f1.y
      GROUP BY f1.x, f1.y
      ORDER BY f1.X

    4-2. 여전히 21 21 페어가 보인다. WHERE 이후에 GROUP BY 가 아닌 먼저 그룹별로 묶고나서 조건을 걸어야 겠다고 생각 -> WHERE 지우고 여기 조건을 HAVING에 쓰기

    SELECT f1.X, f1.Y
    FROM Functions AS f1
    	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
    GROUP BY f1.x, f1.y
    HAVING f1.x<=f1.y
    ORDER BY f1.X

    4-3. 아직도 뭔가 중복이 계속있는 느낌. HAVING 조건을 차례차례 확인해보기로 생각 -> f1.x<f1.y 만 일단 확인

    SELECT f1.X, f1.Y
    FROM Functions AS f1
    	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
    GROUP BY f1.x, f1.y
    HAVING f1.x<f1.y
    ORDER BY f1.X


  4. 이제 중복적인 대칭은 제거 된거같지만 = 조건을 뺏음으로 아직 오류가 있다. 같은 조건이 뭐가 있는지 확인하기 위해 예시 쿼리문을 작성

    SELECT X,Y
    FROM Functions
    GROUP BY X,Y
    

    5-1. 많아서 확인하기 힘들어서 출력에 개수를 보기 위해 -> SELECT문에 Count(*)

    SELECT X,Y, COUNT(*)
    FROM Functions
    GROUP BY X,Y   

    5-2. 다 개수가 1개 인거같아서 눈으로는 보기 힘들다. 따라서 1개 초과 하는게 있는지 확인-> HAVING COUNT(*) >1

    SELECT X,Y, COUNT(*)
    FROM Functions
    GROUP BY X,Y
    HAVING COUNT(*) >1    


    5-3. 13 13 페어가 2개씩인 걸 확인 -> 아까 4번에서 작성했던 쿼리에 HAVING절에서 COUNT(*) >1 을 OR을 써서 추가

    SELECT f1.X, f1.Y
    FROM Functions AS f1
    	INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
    GROUP BY f1.x, f1.y
    HAVING f1.x<f1.y OR COUNT(*) >1    
    ORDER BY f1.X



드디어 정답!


  • 추가로 생각할 수 있는점:
    대칭이 이루어질려면 페어가 짝수여야 함으로 2로 나누었을 때 0으로 생각
SELECT f1.X, f1.Y
FROM Functions AS f1
    INNER JOIN Functions AS f2 ON f1.X = f2.Y AND f2.X = f1.Y
GROUP BY f1.x, f1.y
HAVING f1.x<f1.y OR COUNT(*) % 2 = 0    
ORDER BY f1.X

풀이2

  • UNION을 써서 풀기
  • HINT: 문제의 output에서 X와 Y가 같은 경우 , X < Y인경우의 쿼리를 나누어서 풀고 UNION으로 합치기
SELECT X,Y
FROM Functions
WHERE X=Y
GROUP BY X, Y 
HAVING COUNT(*)>1

UNION

SELECT f1.X, f1.Y
FROM Functions AS f1
    INNER JOIN Functions As f2 ON f1.X = f2.y AND f2.X = f1.Y
WHERE f1.X < f1.Y
ORDER BY X
profile
IT컨설팅 데이터 분석가

0개의 댓글