SELECT daily_stats.week
,AVG(daily_stats.incidents_daily)
FROM (
SELECT week
,date
,COUNT(incident_id) AS incidents_daily
FROM crimes
GROUP BY week, date
) daily_stats
GROUP BY daily_stats.week
AVG() 사용할 때, NULL 카운트가 안 되는 점을 고려해서 SQL문을 작성해야 함
WHERE절 서브쿼리
서브쿼리의 결과가 딱 하나일 경우 (주로 MIN, MAX 사용)
SELECT *
FROM crimes
WHERE date = (SELECT MIN(date) FROM crimes)
서브쿼리의 결과가 여러 개인 경우
SELECT *
FROM crimes
WHERE date IN (SELECT DISTINCT date
FROM crimes
ORDER BY date DESC
LIMIT 5
)
문제 ) salary * months 의 결과값 중에 가장 큰 값을 몇 명이 받고 있는지 조회해라
1) WHERE절 서브쿼리에서 WHERE = 를 사용한 풀이
-- salary * months = earnings 값이 제일 큰 사람
SELECT months * salary AS earnings
, count(employee_id)
FROM Employee
WHERE months * salary = (SELECT MAX(months * salary) FROM employee)
GROUP BY earnings
2) HAVING절 서브쿼리를 사용한 풀이
SELECT months * salary AS earnings
,COUNT(*)
FROM Employee
GROUP BY earnings
HAVING earnings = (SELECT MAX(months * salary) FROM Employee)
SELECT d.name AS department
, e.name AS employee
, e.salary
FROM employee AS e
INNER JOIN (SELECT departmentid
, MAX(salary) AS max_salary
FROM employee
GROUP BY departmentid
) AS dh ON e.departmentid = dh.departmentid
AND e.salary = dh.max_salary
INNER JOIN department AS d ON d.id = e.departmentid
-- product 테이블에서 Price가 5이하 또는 200 이상인 상품들만 출력하세요
SELECT *
FROM Products
WHERE price <= 5
UNION
SELECT *
FROM Products
WHERE price >= 200
FULL OUTER JOIN (MySQL에선 지원 안되지만 LEFT와 RIGHT를 사용해서 구현)
고객정보는 있지만 주문 정보는 없을 때
주문 정보는 있지만 고객 정보는 없을 때 를 모두 조회하고 싶다면 LEFT 조인과 RIGHT 조인을 UNION 해준다
SELECT *
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
UNION
SELECT *
FROM Customers
RIGHT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
/*
20 20 (2번 나와야함 모두)
UNION
20 21
22 23
*/
-- 20 20 케이스 도출
SELECT x, y
FROM Functions
WHERE x = y
GROUP BY x, y
HAVING count(*) = 2
UNION
SELECT a.x
, a.y
FROM Functions AS a
INNER JOIN Functions AS b ON a.x = b.y AND a.y = b.x
WHERE a.x < a.y
ORDER BY x