What a Beautiful Data!

MySQL, 헷갈리고 까먹는 것 모음집

by darami

SQL은 어떤 사이트로 연습하는 게 좋을까요? 해커랭크, 리트코드, Solvesql, 프로그래머스 등 문제를 다 풀고 또다시 몇 번씩 풀어 보았는데요. 풀었던 문제도 다시 풀어보면 막히곤 합니다. 그래서 자주, 고급 sql을 쓰는 것이 실력을 잃지 않는 방법인 것 같습니다. 같은걸 계속 다시 풀다 보니.. 더 이상 문제가 없어 저는 Leedcode 프리미엄을 결제해서 추가 SQL 문제를 풀고 있는데, 리트코드가 특히 다양한 사람들의 솔루션을 비교해서 다양한 풀이 방법으로 볼 수 있고. 솔루션도 제공 / 쿼리 성능 제공 / 이런 부분이 있어서 가장 좋은 것 같습니다. 

프리미엄으로 연습하면서, mysql을 사용하면서 자주 헷갈리고 실수하는 것들을 모아 정리해 보았습니다. 

 

헷갈리는 것 

  • 소수점 둘째자리까지 출력: ROUND ( ,2)  / 소수점 셋째 자리에서 반올림 ROUND(,2) 
  • BETWEEN A AND B  : B까지 포함이나 날짜일 경우 2024-12-25 00시로 측정됨으로 주의 
  • OUTER JOIN은 MySQL에서 작동하지 않음으로 MS SQL을 쓰거나  UNION ALL로 처리해야 함 
  • WHERE __ IN  이나  WHERE   = / IN  (SELECT  FROM) 절을 쓰면 생각보다 많은 것을 처리할 수 있다. 
  • WINDOW 함수는 SELECT절이나 ORDER BY 구문에서만 쓸 수 있다. 조건을 걸고 싶으면 서브 쿼리나 WITH절!  
  • SELECT DISTINCT 칼럼 1, 칼럼 2는 컬럼 2개 전체에서 작용한다 (둘 다 중복된 것만 제거) 
  • 그냥 JOIN 하면 NULL인 것들 사라지니 LEFT JOIN 해야 하지는 않나 확인 해보기 

 

마지막 확인 

  • NULL 처리 했니? (IFNULL 등 사용 가능)
  • ORDER BY 제대로 처리했니? 
  • 컬럼 이름 원하는 대로 붙여 줬니?
  • 쿼리 마지막에 ; 붙였니?  

 

실수하는 부분 

  • [ ELSE NULL END 붙여 ] CASE WHEN           THEN  까지 쓰고 ELSE NULL END 안 붙이지는 않았니?
  • [ PARTITION BY 오타 ] 를 PARRITION으로 쓰지는 않았니? 
  • [ _ 혹시? ] managerid 인데 습관적으로 manager_id 이렇게 쓰지는 않았니? 
  • [ 컬럼, 테이블 명 오타 ] 나지는 않았니? 

 

함수 

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

DELETE FROM table_name WHERE condition;

 

SELECT * FROM Products
WHERE Price NOT BETWEEN 10 AND 20;

 

NULL 처리

COALESCE(UnitsOnOrder, 0)  IFNULL(UnitsOnOrder, 0)

 

DATE 처리 

시간 더하기

mysql / presto / ms sql  등에 따라 함수에 차이가 있어 헷갈리곤 합니다. 

  • DATE_ADD (컬럼  INTERVAL 1 DAY)
  • DATE_SUB (컬럼 ,   INTERVAL 1 DAY)
  • DATEDIFF(작은 날짜 ,  큰 날짜)
  • TIMESTAMPDIFF( YEAR ,  작은 날짜 , 큰 날짜 )

 

순위 정하기 

  • ROW_NUMBER: 어떻게든 순위 정해줌, 중복 순위 X / EX) 1>2>3>4
  • RANK(): 중복 순위 O / EX) 1>1>3>4>4>5
  • DENSE_RANK(): 중복 순위 O, 빠지는 숫자 없음 / EX) 1>1>2>3>3>3

 

연속 5일 예시 

with cte as
(
select
id, login_date,
row_number() over(partition by id order by login_date) as rn
from (select distinct id, login_date from Logins) as distinct_logins
)
select distinct cte.id, `name` -- avoid having same users
from cte
inner join Accounts using(id)
group by 1, login_date - interval rn day -- avoid having same user with continusous but less than 5 records
having count(*) >= 5
order by 1;

 

 

레퍼런스 

 

블로그의 프로필 사진

블로그의 정보

다람

darami

활동하기