< 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
복사
•
주문을 한 고객 리스트를 먼저 확인하기 → 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
복사
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
복사