SELECT, INSERT, UPDATE, DELETE에 포함된 query
SELECT id, name, position -- id, 이름, 직군
FROM employee
WHERE (dept_id, sex) = ( -- 동일한
SELECT dept_id, sex -- 부서, 성별과
FROM employee
WHERE id = 1 -- id가 1인 임직원의
);
ex) ID가 5인 임직원과 같은 프로젝트에 참여한 임직원들의 ID
SELECT DISTINCT empl_id
FROM works_on
WHERE empl_id != 5 -- id가 5인 임직원 제외하고
AND proj_id IN( -- 중에서
SELECT proj_id FROM works_on WHERE empl_id = 5); -- ID가 5인 임직원이 참여한 프로젝트
ex) ID가 7 혹은 12인 임직원이 참여한 프로젝트의 ID와 이름
SELECT P.id, P.name
FROM project P
WHERE EXISTS(
SELECT *
FROM works_on W -- works_on에 존재한다면
WHERE W.proj_id = P.id -- works_on의 id와 project의 id가 동일하고
AND W.empl_id IN (7,12) -- works_on의 empl_id가 7이거나 12인 것
);
ex) 리더보다 높은 연봉을 받는 부서원을 가진 리더의 ID와 연봉
SELECT E.id, E.name, E.salary
FROM department D, employee E
WHERE D.leader_id = E.id AND E.salary < ANY (
SELECT salary
FROM employee
WHERE id <> D.leader_id AND dept_id = E.dept_id
);
ex) ID가 13인 임직원과 한번도 같은 프로젝트에 참여하지 못한 임직원들의 ID, 이름, 직군
SELECT DISTINCT E.id, E.name, E.position
FROM employee E, works_on W
WHERE E.id = W.empl_id AND W.proj_id <> ALL(
SELECT proj_id
FROM works_on
WHERE empl_id = 13
);
unknown, unavailable, not applicable
three-value logic : 비교/논리 연산의 결과로 True, False, Unknown을 가진다.
UNKNOWN
SELECT D.id, D.name
FROM department AS D
WHERE D.id NOT IN(
SELECT E.dept_id
FROM employee E
WHERE E.birth_date >= '2000-01-01'
AND E.dept_id IS NOT NULL
SELECT D.id, D.name
FROM department AS D
WHERE NOT EXISTS(
SELECT *
FROM employee E
WHERE E.dept_id = D.id AND E.birth_date >= '2000-01-01'
두 개 이상의 table들에 있는 데이터를 한 번에 조회하는 것
implicit join
-- ID가 1인 임직원이 속한 부서 이름
SELECT D.name
FROM employee AS E, department AS D
WHERE E.id = 1 and E.dept_id = D.id;
explicit join
-- ID가 1인 임직원이 속한 부서 이름
SELECT D.name
FROM employee AS E JOIN department AS D ON E.dept_id = D.id
WHERE E.id=1;
inner join
SELECT *
FROM employee E INNER JOIN department D ON E.dept_id = D.id;
outer join
두 table에서 join condition을 만족하지 않는 tuple들로 result table에 포함하는 join
join condition에 비교 연산자 사용 가능
FROM table1 LEFT [OUTER] JOIN table2 ON join_condition
SELECT *
FROM employee E LEFT OUTER JOIN department D ON E.dept_id = D.id;

FROM table1 RIGHT [OUTER] JOIN table2 ON join_condition
SELECT *
FROM employee E RIGHT OUTER JOIN department D ON E.dept_id = D.id;

FROM table1 FULL [OUTER] JOIN table2 ON join_condition
SELECT *
FROM employee E FULL OUTER JOIN department D ON E.dept_id = D.id;

SELECT *
FROM employee E FULL OUTER JOIN department D USING (dept_id);SELECT *
FROM employee E NATURAL INNER JOIN department D;

=> SELECT employee CROSS JOIN deparment; 하면

ID가 1003인 부서에 속하는 임직원 중 리더를 제외한 부서원의 ID, 이름, 연봉
SELECT E.id, E.name, E.salary
FROM employee E JOIN department D ON E.dept_id = D.id
WHERE E.dept_id = 1003 and E.id != D.leader_id; -- ID가 1003인 부서 이고, 리더가 아닌 임직원 중에서
ID가 2001인 프로젝트에 참여한 임직원들의 이름, 직군, 소속 부서 이름
SELECT E.name AS empl_name,
E.position AS empl_position,
D.name AS dept_name
FROM works_on W JOIN employee E ON W.empl_id = E.id
LEFT JOIN department D ON E.dept_id = D.id
WHERE W.proj_id = 2001;
✔️이때, LEFT JOIN을 하는 이유는❓
E.dept_id가 null인 경우에도, join 했을 때 employee 정보가 남아있기 위해서
SELECT * FROM employee ORDER BY dept_id, ASC, salary DESC;
✔️이때, 오름차순 정렬 시 NULL을 우선적으로❗
SELECT COUNT(*), MAX(salary), MIN(salary), AVG(salary) -- 임직원 수, 최대 연봉, 최소 연봉, 평균 연봉
FROM works_on W JOIN employee E ON W.empl_id = E.id
WHERE W.proj_id = 2002; -- 프로젝트 2002에 참여한
SELECT W.proj_id, COUNT(*), MAX(salary), MIN(salary), AVG(salary)
FROM works_on W JOIN employee E ON W.empl_id = E.id
GROUP BY W.proj_id;
✔️ 이때 그룹화 기준인 W.proj_id를 적어줘야 한다.
SELECT W.proj_id, COUNT(*), MAX(salary), MIN(salary), AVG(salary)
FROM works_on W JOIN employee E ON W.empl_id = E.id
GROUP BY W.proj_id
HAVING COUNT(*) >= 7;
SELECT dept_id, sex, COUNT(*) AS empl_count FROM employee
GROUP BY dept_id,sex;
ORDER BY empl_count DESC;
SELECT dept_id, AVG(salary)
FROM employee
GROUP BY dept_id
HAVING AVG(salary) <
(SELECT AVG(salary) FROM employee);
SELECT proj_id, COUNT(*), ROUND(AVG(salary), 0)
FROM works_on W JOIN employee E ON W.empl_id = E.id
WHERE E.birth_date BETWEEN '1990-0101' AND '1999-12-31'
GROUP BY W.proj_id;
ORDER BY W.proj_id; -- proj_id를 기준으로 정렬
SELECT proj_id, COUNT(*), ROUND(AVG(salary),0)
FROM works_ond W JOIN employee E ON w.empl_id = E.id
WHERE E.birth_date BETWEEN '1990-01-01' AND '1999-12-31'
AND W.proj_id IN (SELECT proj_id FROM works_on GROUP BY proj_id HAVING COUNT(*) >=7)
GROUP BY W.proj_id
ORDER BY W.proj_id;
SELECT attribute or aggregate function -- 6
FROM table -- 1
[ WHERE condition ] -- 2
[ GROUP BY group attribute ] -- 3
[ HAVING group condition ] -- 4
[ ORDER BY attribute ] -- 5