PostgresSQL/PostgresSQL 수강일지

[수강일지 24] select 3(order by, group by)

jamk-diary 2026. 6. 12. 16:42


--테이블 내용을 아래 구문을 사용해서 매번 확인하기 번거로울 때 
--왼쪽 카테고리 란에서 원하는 테이블 클릭 , 상단 창에서 objext explorer 옆에 있는 표모양 클릭
--새창 생기면서 테이블 내용들만 확인할 수 있게 된다 

-- asc: 오름차순 정리
/*
oder by == sriting (정렬) -> 오름,내림

*/

 SELECT employee_id, salary
 from employees
 order by ;

--테이블 내용을 아래 구문을 사용해서 매번 확인하기 번거로울 때 
--왼쪽 카테고리 란에서 원하는 테이블 클릭 , 상단 창에서 objext explorer 옆에 있는 표모양 클릭
--새창 생기면서 테이블 내용들만 확인할 수 있게 된다 
'select * 
from ;'

-- asc: 오름차순 정리
 SELECT employee_id, hire_date
 from employees
 order by hire_date asc; 

 -- asc: 오름차순 정리 문구는 생략이 가능하다 
 --출력시 자동으로 오름차순 정리 된다 

/* oder by == sriting (정렬) -> 오름,내림 */

SELECT employee_id, salary
 from employees
 order by ;

--테이블 내용을 아래 구문을 사용해서 매번 확인하기 번거로울 때 
--왼쪽 카테고리 란에서 원하는 테이블 클릭 , 상단 창에서 objext explorer 옆에 있는 표모양 클릭
--새창 생기면서 테이블 내용들만 확인할 수 있게 된다 
select * 
from 

-- asc: 오름차순 정리
 SELECT employee_id, hire_date
 from employees
 order by hire_date asc; 

 -- asc: 오름차순 정리 문구는 생략이 가능하다 
 --출력시 자동으로 오름차순 정리 된다 

 

--oder by == sriting (정렬) 
--  desc: 내림
 --desc: 내림차순 정리 
SELECT first_name, salary
from employees
order by salary desc; -- salary를 내림차순으로 정리해 줘 


--IT 부서에 근무하는 사원의 월급을 많이 받는 순으로 정렬하라 -> 내림차순으로 출력하라 
SELECT employee_id, first_name, job_id, salary
from employees
where job_id = 'IT_PROG'
ORDER by salary desc; --오더 문구는 항상 맨 아래에 넣기 

--월급을 내림차순으로 정리하되, 이름은 오름차순으로 정리 
SELECT salary, first_name
from employees
order by salary desc, first_name asc;


--매니저 아이디를 오름차순 기준으로 정렬 
--근데 맨 아래에 null 존재 
SELECT first_name, manager_id
from employees
order by manager_id asc;

-- null인 경우 제일 처음으로 해서 출력하기 
SELECT first_name, manager_id
from employees
order by manager_id asc nulls FIRST;

--역순 정리 
--null 이 맨 위로 온다 
select first_name, commission_pct
from employees
order by commission_pct desc;

select first_name, commission_pct
from employees
--where commission_pct is not null // nulls last 안 쓰고 같은 상황일 때 where 문 더 자주 사용 
order by commission_pct desc nulls last ; --굳이: null 값은 출력 안 함함

--연봉 출력하기 
select FIRST_name, salary * 12 as 연봉 
from employees
order by salary * 12 desc;

-- select 에서 별명을 연봉으로 설정해서 order에서 연봉이라고 써도 같은 값 출력 
select FIRST_name, salary * 12 as 연봉
from employees
order by 연봉  desc;

select FIRST_name, salary * ((12/2)+6) as 연봉 
from employees
order by salary * 12 desc;

/*
group by: 그룹으로 묶는 기능. 통계를 위해서 
group function : count , sum , avg , max , min ... 표준편차 

 having : 그룹으로 묶은 후의 조건 

 distinct : select 절에서만 묶는 데  사용이 가능하다 
*/

-- 이렇게 출력하면 몇 번까지 있는지 너무 헷갈린다 이럴 때 묶어서 사용하는 것이  distinct

--distinct 사용 전 
select  department_id
from employees;

--distinct 사용 후 
select distinct department_id
from employees;

--distinct 사용시 order by와의 조합 
select distinct department_id
from employees;
order by department_id asc;

--에러에러
--distinct 사용 시 두 번 사용하는 건 불가능 반드시 하나의 카테고리로만 묶을 수 있다 
select distinct department_id, distinct job id 
from employees;
order by department_id asc;

select distinct distinct job_id 
from employees;
order by job_id asc;

 

 order by , group by, having 
ORDER BY

언제/왜 써?

데이터를 다 뽑았는데 순서가 뒤죽박죽이면 보기 힘들잖아? 결과를 오름차순(점점 커지게: ASC)이나 내림차순(점점 작아지게: DESC)으로 정렬해서 보고 싶을 때 써.

 

어떻게 작동해?

모든 연산이 다 끝나고 화면에 출력되기 직전 맨 마지막에 작동해. 그래서 SQL 구문을 쓸 때도 무조건 맨 마지막 줄에 적어야 해!

 

SELECT first_name, salary
FROM employees
ORDER BY salary DESC; -- 👈 월급이 많은 사람부터 적은 사람 순으로(내림차순) 정렬해줘!
GROUP BY

"그룹별로 묶어서 통계 낼 때"

 

언제/왜 써?

사원 100명의 데이터를 주르륵 보는 게 아니라, "부서별 평균 월급", "직업별 총 인원수"처럼 데이터를 종류별로 끼리끼리 묶어서 '통계(합계, 평균, 개수 등)'를 내고 싶을 때 무조건 사용해.

 

어떻게 작동해?

컴퓨터한테 "부서 번호(department_id)로 묶어라!"라고 명령하면, 같은 부서에 사는 사원들을 하나의 주머니 속에 한데 모아버려.

SELECT department_id, COUNT(*), AVG(salary)
FROM employees
GROUP BY department_id; -- 👈 부서별로 묶어서(GROUP BY) 인원수랑 평균 월급 보여줘!

//주의주의

주머니 속에 사원들이 다 구겨져 들어갔기 때문에, SELECT 절에는 **묶은 기준(department_id)**이나 **통계 함수(COUNT, SUM, AVG)**만 쓸 수 있어. 개별 사원의 이름(first_name) 같은 건 주머니 안에서 섞여서 누군지 알 수 없기 때문에 출력하면 에러가 나!

HAVING

"그룹화된 통계 결과에 지우개(조건)를 들이밀 때"

 

언제/왜 써?

우리가 평소에 쓰는 WHERE 절은 데이터가 묶이기 전에 '개별 사원'을 걸러내는 지우개야. (예: 월급이 5000 이상인 사원만 골라라). 반면, HAVING은 GROUP BY로 이미 다 묶여서 나온 '통계 결과'에 대고 조건을 걸 때 쓰는 특수 지우개야!

 

차이점 예시

WHERE salary >= 5000 ➡️ 개별 월급이 5000 이상인 사람만 골라라! (⭕ 가능)

WHERE   AVG(salary) >= 5000 ➡️ (❌ 에러!) 아직 묶지도 않았는데 어떻게 평균을 구해!

HAVING AVG(salary) >= 5000 ➡️ (⭕ 정답!) 부서별로 다 묶어서 평균 낸 다음에, 그 평균이 5000 이상인 부서만 남겨라!

 

 

SELECT job_id, SUM(salary)
FROM employees
GROUP BY job_id
HAVING SUM(salary) >= 150000; -- 👈 업무별로 다 더한 '합계'가 15만 불 이상인 그룹만 남겨라!

 

컴퓨터의 일 처리 순서 

컴퓨터는 우리가 코드를 적은 순서대로 일하지 않고, 철저한 내부 규칙에 따라 움직여. 이 순서대로 기억하면 헷갈릴 일이 절대 없어!
  1. FROM : 어떤 테이블에서 데이터를 가져올지 고른다.
  2. WHERE : 개별 데이터 중에 불필요한 걸 먼저 지우개로 지운다.
  3. GROUP BY : 남은 데이터들을 주머니에 종류별로 묶는다.
  4. HAVING : 묶여서 나온 통계 결과 중에 조건에 안 맞는 주머니를 버린다.
  5. SELECT : 최종적으로 화면에 보여줄 칼럼만 쏙쏙 뽑아낸다.
  6. ORDER BY : 화면에 보여주기 직전, 보기 좋게 정렬한다! (언제나 꼴찌!)


--GROUP by 랑 같이 쓰기 
select  department_id
from employees
GROUP by department_id;

--GROUP by 랑 order by 같이 쓰기 
select  department_id
from employees
GROUP by department_id
order by department_id asc;


-- group function 
SELECT count (employee_id), sum(salary), avg(salary),
 max(salary), min(salary)
from employees
where job_id = 'IT_PROG';

SELECT count (employee_id), sum(salary), trunc(avg(salary)),
 max(salary), min(salary)
from employees
where job_id = 'IT_PROG';


-- 그룹 바이로 부서번호로 묶고 나서 실행하기 
SELECT department_id,  count(*), sum(salary), round(avg(salary),1),
  max(salary), min(salary)
from employees
group by department_id; 

--업무 별로 급여의 합계(sum)가 15000불 이상인 업무 명을 출력하라 

--에러에러 
select * 
from employees
group by job_id
having sum (salary) >= 150000;

-- 업무 (job_id)별로 급여의 합계가  (sum )150000 이상인 사람을 출력 
--group by 로 묶었을 떄는 반드시 묶은 칼럼으로만 볼 수 있다 
select job_id,sum (salary) 
from employees
group by job_id
having sum (salary) >= 150000; --having 절은 묶음에 들어간다 

--grou buy 를 반드시 하나로 묶어야 되는 것은 아니다 
--20번 부서로 묶은 다음에 그 안에서  따로 묶은 것 20 | "MK_REP"  20 | "MK_MAN"
-- 부서로 묶고 업무로 한 번 더 묶기 
SELECT department_id, job_id
from employees
GROUP by department_id, job_id
order by department_id asc;
 

강사님 과제 work 2

 

-- order by
-- 문제1) EMPLOYEES 테이블에서 입사일자 순으로 정렬한 사원번호, 이름, 업무, 급여, 입사일자,부서번호를 출력하라.


-- 문제2) EMPLOYEES 테이블에서 가장 최근에 입사한 순으로 정렬한 사원번호, 이름, 업무, 급여, 입사일자,부서번호를 출력하라.


-- 문제3) EMPLOYEES 테이블에서 부서번호로 정렬한 후 부서번호가 같을 경우, 급여가 많은 순으로 정렬한 사원번호, 성명, 업무, 부서번호, 급여를 출력하여라.


-- 문제4) EMPLOYEES 테이블에서 첫번째 정렬은 부서번호로 두번째 정렬은 업무로 세번째 정렬은 급여가 많은 순으로 정렬한 사원번호, 성명, 입사일자, 부서번호, 업무, 급여를 출력하여라.



-- 그룹핑
-- 문제1) EMPLOYEES 테이블에서 모든 SALESMAN(SA_)에 대하여 급여의 평균, 최고액, 최저액, 합계를 구하여 출력하여라.


-- 문제2) EMPLOYEES 테이블에 등록되어 있는 인원수, 보너스가 NULL이 아닌 인원수, 보너스의 평균, 등록되어 있는 부서의 수를 구하여 출력하라.


-- 문제3) EMPLOYEES 테이블에서 부서별로 인원수, 평균 급여, 최저급여, 최고 급여, 급여의 합을 구하여 출력하라.


-- 문제4) EMPLOYEES 테이블에서 각 부서별로 인원수, 급여의 평균, 최저 급여, 최고 급여, 급여의 합을 구하여 급여의 합이 많은 순으로 출력하여라.


-- 문제5) EMPLOYEES 테이블에서 부서별, 업무별 그룹하여 결과를 부서번호, 업무, 인원수, 급여의 평균, 급여의 합을 구하여 출력하여라.


-- 문제6) EMPLOYEES 테이블에서 부서 인원이 4명보다 많은 부서의 부서번호, 인원수, 급여의 합을 구하여 출력하여라


-- 문제7) EMPLOYEES 테이블에서 급여가 최대 10000이상인 부서에 대해서 부서번호, 평균 급여, 급여의 합을 구하여 출력하여라.


-- 문제8) EMPLOYEES 테이블에서 업무별 급여의 평균이 10000 이상인 업무에 대해서 업무명,평균 급여, 급여의 합을 구하여 출력하라.


-- 문제9) EMPLOYEES 테이블에서 전체 월급이 10000을 초과하는 각 업무에 대해서 업무와 월급여 합계를 출력하라. 
-- 단 판매원(SA_)은 제외하고 급여 합계로 정렬(내림차순)하라.

-- order by ⭕❌
-- 문제1) EMPLOYEES 테이블에서 입사일자 순으로 정렬한 사원번호, 이름, 업무, 급여, 입사일자,부서번호를 출력하라.
SELECT  employee_id, ("last_name" ||' ' || "first_name") as name ,  job_id , salary, department_id
from employees
order by manager_id asc; ❌ -> ⭕

SELECT employee_id, last_name , job_id , hire_date , department_id
from employees
order by hire_date;



-- 문제2) EMPLOYEES 테이블에서 가장 최근에 입사한 순으로 정렬한 사원번호, 이름, 업무, 급여, 입사일자,부서번호를 출력하라.
SELECT  employee_id, ("last_name" ||' ' || "first_name") as name ,  job_id ,  department_id,salary
from employees
order by manager_id desc; ❌ -> ⭕

SELECT employee_id, last_name , salary , hire_date , department_id
from employees
order by hire_date desc;



-- 문제3) EMPLOYEES 테이블에서 부서번호로 정렬한 후 부서번호가 같을 경우, 급여가 많은 순으로 정렬한 사원번호, 성명, 업무, 부서번호, 급여를 출력하여라.
SELECT  employee_id, ("last_name" ||' ' || "first_name") as name ,   job_id ,  department_id,salary
from employees
group by department_id,employee_id
order by department_id asc, salary desc nulls first;  ❌ -> ❌

💡 왜 GROUP BY를 쓰면 안 될까?

  • GROUP BY는 언제 써?
    • 부서별 '평균 급여', 부서별 '총 인원수'처럼 데이터를 한데 뭉뚱그려서 통계(집계)를 내고 싶을 때만 쓰는 친구야.
  • 이 문제는 뭘 원해?
    • 사원들의 사원번호, 성명, 업무, 급여 등 개개인의 상세 정보를 그대로 다 보여달라고 하고 있지?
    • GROUP BY를 써버리면 개별 사원들의 정보가 부서라는 주머니 속으로 다 구겨져 들어가서 개개인의 데이터를 볼 수가 없게 돼.
즉, 이 문제는 묶는 문제가 아니라, 그냥 전체 사원을 주르륵 출력하되 보기 좋게 정렬(ORDER BY)만 잘해달라는 문제야!

🛠️ 정렬 조건 정석대로 조립하기

문제에서 정렬 조건을 2개 줬어.
  1. 1순위: 부서번호 순서대로 (department_id ASC)
  2. 2순위: 부서번호가 같으면 급여가 많은 순서대로 (salary DESC)
ORDER BY 뒤에 쉼표(,)를 찍고 1순위, 2순위 정렬 기준을 차례대로 적어주기만 하면 끝이야!



-- 문제4) EMPLOYEES 테이블에서 첫번째 정렬은 부서번호로 두번째 정렬은 업무로 세번째 정렬은 급여가 많은 순으로 정렬한 사원번호, 성명, 입사일자, 부서번호, 업무, 급여를 출력하여라.
SELECT  employee_id, ("last_name" ||' ' || "first_name") as name ,   hire_date ,  department_id,salary
from employees ⭕

order by department_id asc, job_id, salary desc nulls first;

-- 그룹핑: 하츄핑
-- 문제1) EMPLOYEES 테이블에서 모든 SALESMAN(SA_)에 대하여 급여의 평균, 최고액, 최저액, 합계를 구하여 출력하여라.

SELECT  avg(salary),sum(salary), max(salary),min(salary)  ,sum(salary)
from  employees
where job_id like 'SA_%' ⭕

-- 문제2) EMPLOYEES 테이블에 등록되어 있는 인원수, 보너스가 NULL이 아닌 인원수, 보너스의 평균, 등록되어 있는 부서의 수를 구하여 출력하라.
SELECT count (employee_id),count(commission_pct ),avg(commission_pct ), count (department_id)
from  employees
where commission_pct is not null; ❌

-- 문제3) EMPLOYEES 테이블에서 부서별로/ 인원수, 평균 급여, 최저급여, 최고 급여, 급여의 합을 구하여 출력하라.
SELECT count (employee_id) as 인원수 ,avg(salary ),MAX(salary ), min(salary), (MAX(salary )+ min(salary)) as 합
from  employees
group by department_id;  ❌

-- 문제4) EMPLOYEES 테이블에서 각 부서별로 인원수, 급여의 평균, 최저 급여, 최고 급여, 급여의 합을 구하여 급여의 합이 많은 순으로 출력하여라.
SELECT count (employee_id) as 인원수 ,avg(salary ),MAX(salary ), min(salary), (MAX(salary )+ min(salary)) as 합
from  employees
group by department_id
order by 합 desc nulls last; ❌

-- 문제5) EMPLOYEES 테이블에서 부서별, 업무별 그룹하여 결과를 부서번호, 업무, 인원수, 급여의 평균, 급여의 합을 구하여 출력하여라.
SELECT department_id, job_id,count(employee_id), avg(salary), sum(salary) as 합 
from  employees
group by department_id, job_id
order by 합 desc nulls last; ⭕

-- 문제6) EMPLOYEES 테이블에서 부서 인원이 4명보다 많은 부서의 부서번호, 인원수, 급여의 합을 구하여 출력하여라
SELECT department_id, count(job_id) as 인원수 ,  sum(salary) as 합 
from  employees
having sum(인원수) >= 5
order by 합 desc nulls last; ❌

-- 문제7) EMPLOYEES 테이블에서 급여가 최대 10000이상인 부서에 대해서 부서번호, 평균 급여, 급여의 합을 구하여 출력하여라.


-- 문제8) EMPLOYEES 테이블에서 업무별 급여의 평균이 10000 이상인 업무에 대해서 업무명,평균 급여, 급여의 합을 구하여 출력하라.


-- 문제9) EMPLOYEES 테이블에서 전체 월급이 10000을 초과하는 각 업무에 대해서 업무와 월급여 합계를 출력하라. 
-- 단 판매원(SA_)은 제외하고 급여 합계로 정렬(내림차순)하라.