Search

Easy

< EASY >

combine two tables

select firstName ,lastName ,CASE WHEN addressId is NULL then NULL ELSE city END as city ,CASE WHEN addressId is NULL then NULL ELSE state END as state from Person A left join Address B ON A.personId = B.personId;
SQL
복사

employees earning more than their managers

where 서브쿼리
select a.Name as Employee from Employee a where a.Salary > (select b.Salary from Employee b where Id = a.managerId);
SQL
복사

duplicate emails

select email as Email from Persons group by email having count(id) >= 2;
SQL
복사

customers who never order

 내 풀이 : 너무 느림..
select c.name as Customers from Customers c left join Orders o on c.id = o.customerId where o.id is null;
SQL
복사
 다른 풀이 ( 482 ms )
주문을 한 고객 리스트를 먼저 확인하기 → select customerid from orders;
위의 리스트에 포함되지 않은 고객을 찾아주기 → not in
select customers.name as 'Customers' from customers where customers.id not in ( select customerid from orders );
SQL
복사

delete duplicate emails

중복데이터 하나만 남기고 제거
1) 자기 자신과 조인
2) 삭제조건은 순서값이 큰 것과 중복되는 값으로 설정
delete a from person a, person b where a.id > b.id # id는 순서값을 가진 칼럼명을 사용한다. and a.email = b.email;
SQL
복사

rising temperature

이전날과 비교해서 온도가 올랐다면 해당 id 출력하기
날짜 차이가 반드시 하루여야 한다는 것을 유의
→ lag 함수를 사용하면 안된다. 이전 레코드 값과 비교만 해주는 함수이므로
→ 대신 날짜 차이를 계산하는 datediff 함수를 사용해야 함
select a.id from weather a, weather b where datediff(a.recordDate, b.recordDate) = 1 and a.temperature > b.temperature;
SQL
복사

game play analysis 1

select player_id ,min(event_date) as first_login from activity group by player_id;
SQL
복사

find customer referee

select name from customer where referee_id <> '2' or referee_id is null
SQL
복사

customer placing the largest number of orders

select customer_number from orders group by customer_number having count(*) >= all(select count(*) from orders group by customer_number);
SQL
복사

classes more than 5 students

select class from courses group by class having count(distinct student) >= 5;
SQL
복사

sales person

서브쿼리 활용
: 전체 영업사원 중 RED 회사에서 영업을 하지 않은 영업사원만 출력 → not in
select name from salesperson where sales_id not in (select sales_id from orders where com_id = (select com_id from company where name = 'RED'))
SQL
복사
 다른 풀이
SELECT s.name FROM salesperson s WHERE s.sales_id NOT IN (SELECT o.sales_id FROM orders o LEFT JOIN company c ON o.com_id = c.com_id WHERE c.name = 'RED')
SQL
복사

not boring movies

select * from cinema where id % 2 = 1 and description <> 'boring' order by rating desc;
SQL
복사

swap salary

update salary set sex = case when sex = 'f' then 'm' else 'f' end
SQL
복사

actors and directors who cooperated at least three times

select actor_id, director_id from actordirector group by actor_id, director_id having count(*) >= 3
SQL
복사

sales analysis 3

select distinct b.product_id, a.product_name from product a inner join sales b on a.product_id = b.product_id where b.product_id not in ( select distinct product_id from sales where sale_date not between '2019-01-01' and '2019-03-31' );
SQL
복사
 다른 풀이
날짜의 최솟값과 최댓값을 활용
select product_id, product_name from sales join product using(product_id) # 필드 이름이 같기 때문에 group by product_id having min(sale_date) >= '2019-01-01' and max(sale_date) <= '2019-03-31'
SQL
복사
 USING VS ON 차이
1.
using
두 테이블 간 필드이름이 같은 경우에 사용한다.
2.
on
두 테이블 간 필드이름이 다를 경우에 사용한다. 하지만 같을 경우에 사용해도 상관 없다.

user activity for the past 30 days 1

select activity_date as day, count(distinct user_id) as active_users from activity where activity_date >= date_sub('2019-07-27',interval 29 day) and activity_date <= '2019-07-27' group by activity_date having count(distinct user_id) > 0
SQL
복사
 다른 풀이
SELECT activity_date AS day , COUNT(DISTINCT user_id) AS active_users FROM Activity WHERE (activity_date > "2019-06-27" AND activity_date <= "2019-07-27") GROUP BY activity_date having count(distinct user_id) > 0;
SQL
복사

article views 1

select distinct author_id as id from views group by author_id having count(if(author_id = viewer_id,1,null)) >= 1 order by id;
SQL
복사

reformat department table

행 데이터 값 → 열의 변수로 변환하기
case when 또는 if
select id ,sum(case when month='Jan' then revenue else null end) as Jan_Revenue ,sum(case when month='Feb' then revenue else null end) as Feb_Revenue ,sum(case when month='Mar' then revenue else null end) as Mar_Revenue ,sum(case when month='Apr' then revenue else null end) as Apr_Revenue ,sum(case when month='May' then revenue else null end) as May_Revenue ,sum(case when month='Jun' then revenue else null end) as Jun_Revenue ,sum(case when month='Jul' then revenue else null end) as Jul_Revenue ,sum(case when month='Aug' then revenue else null end) as Aug_Revenue ,sum(case when month='Sep' then revenue else null end) as Sep_Revenue ,sum(case when month='Oct' then revenue else null end) as Oct_Revenue ,sum(case when month='Nov' then revenue else null end) as Nov_Revenue ,sum(case when month='Dec' then revenue else null end) as Dec_Revenue from department group by id;
SQL
복사

top travellers

select u.name as name ,ifnull(sum(r.distance),0) as travelled_distance from users u left join rides r on u.id = r.user_id group by u.id, u.name order by travelled_distance desc, name;
SQL
복사

group sold products by the date

group_concat
그룹별로 데이터를 concatenate 하는 방법
select sell_date ,count(distinct product) as num_sold ,group_concat(distinct product order by product) as products from activities group by sell_date order by sell_date;
SQL
복사

patients with a condition

select patient_id ,patient_name ,conditions from patients where conditions like 'DIAB1%' OR conditions like '%DIAB1%';
SQL
복사

customer who visited but did not make any transactions

select customer_id ,count(*) as count_no_trans from visits where visit_id not in (select visit_id from transactions) group by customer_id;
SQL
복사

bank account summary 2

select u.name ,sum(t.amount) as balance from users u left join transactions t on u.account = t.account group by u.account having sum(t.amount) > 10000;
SQL
복사

fix names in a table

문자열 자르기
left(컬럼명 또는 문자열, 왼쪽에서 잘라낸 문자열의 길이) : 왼쪽에서부터 자르기
right(컬럼명 또는 문자열, 오른쪽에서 잘라낸 문자열의 길이) : 오른쪽에서부터 자르기
substr(컬럼명 또는 문자열, 시작위치, [길이]) : 중간에서 잘라내기
mid(컬럼명 또는 문자열, 시작위치, [길이]) # 중간에서 잘라내기 (= substr)
소문자 대문자 변환
upper(컬럼명 또는 문자열)
lower(컬럼명 또는 문자열)
문자열 합치기
concat()
select user_id ,concat(upper(left(name,1)),lower(substr(name,2))) as name from users order by user_id;
SQL
복사

daily leads and partners

select date_id ,make_name ,count(distinct lead_id) as unique_leads ,count(distinct partner_id) as unique_partners from dailysales group by date_id, make_name;
SQL
복사

find followers count

select user_id ,count(distinct follower_id) as followers_count from followers group by user_id order by user_id;
SQL
복사

find total time spent by each employee

select event_day as day ,emp_id ,sum(out_time - in_time) as total_time from employees group by emp_id, event_day;
SQL
복사

recyclable and low fat products

select product_id from products where low_fats = 'Y' and recyclable = 'Y';
SQL
복사

rearrange products table

분리되어 있는 열들을 행의 데이터 값으로 변환하기
분리된 열들에 대해서 각자 처리한 뒤 union all(중복 포함) 해주기
예를 들어, 아래와 같이 생긴 테이블을
product_id
store1
store2
store3
1
95
100
105
2
70
null
80
다음과 같이 변경한다고 할 때
product_id
store
price
1
store1
95
1
store2
100
1
store3
105
2
store1
70
2
store3
80
아래와 같이 코드를 구성하면 된다.
select product_id ,'store1' as store ,store1 as price from products where store1 is not null union all select product_id ,'store2' as store ,store2 as price from products where store2 is not null union all select product_id ,'store3' as store ,store3 as price from products where store3 is not null
SQL
복사

calculate special bonus

select employee_id ,case when name not like 'M%' and employee_id % 2 = 1 then salary else 0 end as bonus from employees order by employee_id;
SQL
복사

the latest login in 2020

select user_id ,max(time_stamp) as last_stamp from logins where year(time_stamp) = '2020' group by user_id;
SQL
복사

employees with missing information

my sql의 full outer join
left join + union + right_join
select case when a.salary is null then e_id when a.name is null then s_id end as employee_id from( select e.employee_id as e_id, e.name as name, s.employee_id as s_id, s.salary as salary from employees e left join salaries s on e.employee_id = s.employee_id union select e.employee_id as e_id, e.name as name, s.employee_id as s_id, s.salary as salary from employees e right join salaries s on s.employee_id = e.employee_id ) a where a.salary is null or a.name is null order by employee_id;
SQL
복사