예)
SELECT * FROM departments
WHERE EXISTS
(SELECT * FROM employees
WHERE departments.department_id = employees.department_id
AND employees.salary > 2500)
ORDER BY department_name;
한줄이라도 존재 한다면 트루,..표시해줘라
한명이라도 부서에 소속된 사람이 있으면 부서를 얻고 사원이 없으면 얻지 않는다.
단독으로 수행 할 수 없고 메인으로 부터 조건을 받아서 수행하는 것
(이게 상관하위질의 이다.)
이경우는 SEMI을 하지 않는다.
왜냐면...
SELECT department_id
FROM departments d
WHERE EXISTS
(SELECT * FROM employees e
WHERE d.department_id
= e.department_id);
EXISTS는 내용이 중요한게 아니라 있냐 없냐!!이게 중요 하다.
EXISTS는 SEMI조인을 되고.
SEMI조인은 INNER 조인이랑거의 비슷하다..
SEMI의 장점은 있냐 없냐라고만 물어봐서 정보를 다 가지고 오는게 아니라 있다고 확인되면 그것만 확인하고 한개 이상의 레코드만 있으면 하나만 읽고 넘겨준다. 머 속도가 빠르겠지
상관하의질의)
예)
SELECT department_id,last_name,salary
FROM employees x
WHERE salary>
(SELECT AVG(salary)
FROM employees
WHERE x.department_id = department_id)
ORDER BY department_id;
이거랑 밑에꺼랑 같은 문장이다. 위에껀 상관하의 질의
SELECT e.department_id,e.last_name,e.salary
FROM employees e JOIN (SELECT department_id , AVG(salary) AS Smax
FROM employees
GROUP BY department_id
) f
ON e.department_id = f.department_id
WHERE salary > Smax
ORDER BY department_id
예제)
c SEATTLE
d DENVER
SELECT custid,city
FROM customers e
WHERE custid NOT IN (SELECT custid
FROM orders
WHERE e.custid = custid
GROUP by custid)
ORDER BY custid;
select c.custid, c.city
from orders o right join customers c
on o.custid = c.custid
where orderid IS NULL
order by custid;
[#M_더보기|접기|select custid, city
from customers c
where NOT EXISTS (select custid
from orders
where c.custid = custid
GROUP by custid)
order by custid;
select custid, city
from customers
MINUS
select o.custid, city
from customers c JOIN orders o
on c.custid = o.custid
_M#]
문제2
씨애틀이 있는 주문을 3번이상 한 사람
SELECT cus.custid ,COUNT(ord.orderid)
FROM customers cus LEFT JOIN orders ord
ON cus.custid = ord.custid
WHERE lower(cus.city) = 'seattle'
GROUP BY cus.custid
HAVING COUNT(ord.orderid)<3;
분석 함수
SELECT department_id
, last_name, salary
, commission_pct,
RANK() OVER ( ORDER BY salary DESC, commission_pct) "Rank"
FROM employees
WHERE department_id = 80;
RANK() OVER(ORDER BY 차순, 기준)
등수가 3이하인걸 나타낼때
SELECT *
FROM (
SELECT department_id
, last_name, salary
, commission_pct,
RANK() OVER (PARTITION BY department_id
ORDER BY salary DESC, commission_pct) rank_salary
FROM employees
WHERE department_id = 80
)--INline View
WHERE rank_salary <=3;
분석함수를 정의 한 후
원하는 것 만큼 짤라 오자
CASE) IF랑 같은거
SELECT employee_id
, salary
, job_id
, CASE
WHEN job_id LIKE'SA%' THEN
'Sales'
ELSE
'Non Salse'
END AS job
, CASE job_id
WHEN 'SA_MAN' THEN 'Salse'
WHEN 'SA_REP' THEN 'Salse'
ELSE
'Non Salse'
END
,DECODE(job_id,'SA_MAN','Salse','SA_REP','Salse','Non Salse')
빨강 파랑 초록이 다 같은 문장 표현이다.
FROM employees
CASE가 DECODE보다 확장성이 더 좋다~~
ROW_NUMBER)
SELECT *
FROM (
SELECT employee_id
, first_name
, phone_number
,hire_date
,ROW_NUMBER() OVER (ORDER BY hire_date ASC, first_name) AS rnk
FROM employees
WHERE job_id LIKE 'SA%'
)
WHERE rnk BETWEEN 11 AND 20;