e문자열 관련
length(): 문자열 길이 — 공통
select length('hello'); -- 5
- Oracle → byte 길이 = lengthb()
- MySQL → byte 길이 = length()
- MySQL 문자수 ('한글' - 2 / byte로 검색하면 6) = char_length()
substr(): 문자열 자르기 — 공통
substr(문자열, 시작, 길이)
select substr('abcdef',1,3); -- abc
select substr('abcdef',-3); -- def
substr(phone,1,3) -- 앞 n글자
substr(phone,-4) -- 뒤 n글자
instr(): 문자열 위치 찾기 — 공통
instr('abcdef','cd') -- 3
instr(email@email.com,'@')
- 없으면: 0 반환
- 전체를 검색해야해서 인덱스를 타지 못해서 성능이 떨어짐.
concat(): 문자열 연결 — 공통
concat('hello','world')
- 여러개 붙이기:
- MySQL: concat(a,b,c,d)
- Oracle: concat(a, concat(b,c))
|| 연산자: 문자열 연결 — 공통
select 'hello' || 'world';
upper(): 대문자 변환 — 공통
upper('abc') → ABC
lower(): 소문자 변환 — 공통
lower('ABC') → abc
replace(): 문자 치환— 공통
replace('hello world','world','sql') → hello sql
replace(phone,'-','') -- 문자 치환
trim(): 양쪽 공백 제거 — 공통
trim(' hello ')
ltrim('hello ') -- 왼쪽만
rtrim('hello ') -- 오른쪽만
lpad(): 왼쪽 채우기 — 공통
lpad('7',3,'0') → 007
rpad(): 오른쪽 채우기 — 공통
rpad('a',5,'*') → a****
like: 패턴 검색— 공통
where name like 'kim%'
- % → 여러 글자
- _ → 한 글자
- %문자%의 경우 인덱스를 타지 못함.(성능이 안좋음.)
regexp_like: 정규식 — Oracle / MySQL8
regexp_like(name,'^a')
MySQL:
regexp
nvl(): null 처리 — Oracle
nvl(col,'값')
ifnull(): null 처리 — MySQL
ifnull(col,'값')
coalesce(): null 처리 — 공통
coalesce(col,'값')
cast(): 문자열 → 숫자 — 공통
cast('123' as int)
날짜 관련
현재 날짜
select sysdate from dual; -- Oracle
select curdate(); -- MySQL
select now(); -- MySQL
select current_date; -- 공통
날짜 + 숫자: 날짜 더하기 / 빼기
날짜 + 1 = 하루 추가
select sysdate + 1 from dual; -- Oracle
select now() + interval 1 day; -- MySQL (정석)
- MySQL은 interval 권장:
date + interval 7 day
date + interval 1 month
date + interval 1 year
datediff(): 날짜 차이 구하기— MySQL
datediff(날짜1, 날짜2)
select datediff('2024-03-10','2024-03-01'); -- 9
날짜 - 날짜: 날짜 차이 구하기 — Oracle
select sysdate - hiredate
- = 일(day) 차이 반환
extract(): 특정 날짜 부분 추출 (년/월/일) — 공통
extract(year from 날짜)
extract(month from 날짜)
extract(day from 날짜)
select extract(year from sysdate) from dual;
select extract(month from now());
where extract(year from date_col) = 2022 -- 특정 년도
where extract(month from date_col) = 5 -- 특정 월
시간
EXTRACT(HOUR FROM datetime)
EXTRACT(MINUTE FROM datetime)
EXTRACT(SECOND FROM datetime)
year(), month(), day() : 특정 날짜 부분 추출 — MySQL
select year(now());
select month(now());
select day(now());
to_char(): 날짜 형식 변환 (문자열 출력) — Oracle
to_char(날짜,'YYYY-MM-DD')
to_char(날짜,'YYYY')
to_char(날짜,'MM')
to_char(날짜,'DD')
시간 출력
TO_CHAR(date, 'HH24:MI:SS')
date_format(): 날짜 형식 변환 (문자열 출력) — MySQL
date_format(날짜,'%Y-%m-%d')
date_format(날짜,'%Y')
date_format(날짜,'%m')
date_format(날짜,'%d')
시간 출력
DATE_FORMAT(date, '%H:%i:%s')
DATE_FORMAT(date, '%T')
to_date(): 문자열 → 날짜 변환 — Oracle
to_date('2024-03-01','YYYY-MM-DD')
str_to_date(): 문자열 → 날짜 변환 — MySQL
str_to_date('2024-03-01','%Y-%m-%d')
날짜 범위 조회: between 사용
where date_col between '2024-01-01' and '2024-01-31'
- 주의: between은 양쪽 포함
특정 월만 조회 (추천)
where date >= '2024-01-01'
and date < '2024-02-01'
add_months(): 달 더하기 — Oracle
add_months(sysdate,3)
date_add(): 달 더하기 — MySQL
date_add(now(), interval 3 month)
last_day(): 월의 마지막날 - 공통
select last_day(sysdate) from dual;
select last_day(now());
요일 구하기 - Oracle
to_char(sysdate,'day')
to_char(sysdate,'dy')
요일 구하기 - MySQL
dayname(now())
weekday(now())
날짜 정렬: 날짜는 문자열로 바꾸지 말고 그냥 date 타입으로 정렬
order by date_col
대여 기록이 존재하는 자동차 리스트 구하기
CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 자동차 종류가 '세단'인 자동차들 중 10월에 대여를 시작한 기록이 있는 자동차 ID 리스트를 출력하는 SQL문을 작성해주세요. 자동차 ID 리스트는 중복이 없어야 하며, 자동차 ID를 기준으로 내림차순 정렬해주세요.
SELECT DISTINCT c.car_id
FROM car_rental_company_car c
JOIN car_rental_company_rental_history h
ON c.car_id = h.car_id
AND EXTRACT(MONTH FROM h.start_date) = 10
WHERE c.car_type = '세단'
ORDER BY c.car_id DESC
조건에 부합하는 중고거래 상태 조회하기
USED_GOODS_BOARD 테이블에서 2022년 10월 5일에 등록된 중고거래 게시물의 게시글 ID, 작성자 ID, 게시글 제목, 가격, 거래상태를 조회하는 SQL문을 작성해주세요. 거래상태가 SALE 이면 판매중, RESERVED이면 예약중, DONE이면 거래완료 분류하여 출력해주시고, 결과는 게시글 ID를 기준으로 내림차순 정렬해주세요.
SELECT board_id, writer_id, title, price,
CASE
WHEN UPPER(status) = 'SALE' THEN '판매중'
WHEN UPPER(status) = 'RESERVED' THEN '예약중'
ELSE '거래완료'
END AS status
FROM used_goods_board
WHERE created_date = DATE '2022-10-05'
ORDER BY board_id DESC
조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기
USED_GOODS_BOARD와 USED_GOODS_FILE 테이블에서 조회수가 가장 높은 중고거래 게시물에 대한 첨부파일 경로를 조회하는 SQL문을 작성해주세요. 첨부파일 경로는 FILE ID를 기준으로 내림차순 정렬해주세요. 기본적인 파일경로는 /home/grep/src/ 이며, 게시글 ID를 기준으로 디렉토리가 구분되고, 파일이름은 파일 ID, 파일 이름, 파일 확장자로 구성되도록 출력해주세요. 조회수가 가장 높은 게시물은 하나만 존재합니다.
-- Oracle
SELECT '/home/grep/src/' || f.board_id || '/' || f.file_id || f.file_name || f.file_ext AS FILE_PATH
FROM used_goods_board b
JOIN used_goods_file f
ON b.board_id = f.board_id
AND b.views = (SELECT MAX(views) FROM used_goods_board)
ORDER BY FILE_PATH DESC
-- MySQL
SELECT CONCAT('/home/grep/src/', f.board_id, '/', f.file_id, f.file_name, f.file_ext) AS FILE_PATH
FROM used_goods_board b
JOIN used_goods_file f
ON b.board_id = f.board_id
AND b.views = (SELECT MAX(views) FROM used_goods_board)
ORDER BY FILE_PATH DESC
- Oracle의 경우 CONCAT()에 하나씩만 연결 할 수 있기 때문에 CONCAT('test', CONCAT('test', 'test')) 이런 식으로 써야한다. 그래서 '||'를 사용하는 편이 좋다.
- MySQL은 CONCAT('test', 'test', 'test', ...)이런 식으로 연결이 가능하다. '||'는 버전에 따라서 사용이 불가능한 거 같다.
조건에 맞는 사용자 정보 조회하기
USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 중고 거래 게시물을 3건 이상 등록한 사용자의 사용자 ID, 닉네임, 전체주소, 전화번호를 조회하는 SQL문을 작성해주세요. 이때, 전체 주소는 시, 도로명 주소, 상세 주소가 함께 출력되도록 해주시고, 전화번호의 경우 xxx-xxxx-xxxx 같은 형태로 하이픈 문자열(-)을 삽입하여 출력해주세요. 결과는 회원 ID를 기준으로 내림차순 정렬해주세요.
-- Oracle
SELECT
user_id, nickname,
city || ' ' || street_address1 || ' ' || street_address2 AS address,
SUBSTR(tlno, 1, 3) || '-' || SUBSTR(tlno, 4, 4) || '-' || SUBSTR(tlno, -4) AS tlno
FROM used_goods_user
WHERE user_id IN (
SELECT writer_id
FROM used_goods_board
GROUP BY writer_id
HAVING COUNT(*) >= 3
)
ORDER BY user_id DESC
-- Oracle
SELECT u.user_id,
u.nickname,
u.city || ' ' || u.street_address1 || ' ' || u.street_address2 AS address,
REGEXP_REPLACE(u.tlno, '(\d{3})(\d{4})(\d{4})', '\1-\2-\3') AS tlno
FROM used_goods_user u
JOIN (
SELECT writer_id
FROM used_goods_board
GROUP BY writer_id
HAVING COUNT(*) >= 3
) b
ON u.user_id = b.writer_id
ORDER BY u.user_id DESC;
-- MySQL
SELECT
u.user_id,
u.nickname,
CONCAT(u.city, ' ', u.street_address1, ' ', u.street_address2) AS address,
CONCAT(SUBSTR(u.tlno, 1, 3), '-', SUBSTR(u.tlno, 4, 4), '-', SUBSTR(u.tlno, -4)) AS tlno
FROM USED_GOODS_USER u
JOIN (
SELECT writer_id
FROM USED_GOODS_BOARD
GROUP BY writer_id
HAVING COUNT(*) >= 3
) b
ON u.user_id = b.writer_id
ORDER BY u.user_id DESC
조건별로 분류하여 주문상태 출력하기
FOOD_ORDER 테이블에서 2022년 5월 1일을 기준으로 주문 ID, 제품 ID, 출고일자, 출고여부를 조회하는 SQL문을 작성해주세요. 출고여부는 2022년 5월 1일까지 출고완료로 이 후 날짜는 출고 대기로 미정이면 출고미정으로 출력해주시고, 결과는 주문 ID를 기준으로 오름차순 정렬해주세요.
-- MySQL
SELECT order_id, product_id, DATE_FORMAT(out_date, '%Y-%m-%d'),
CASE
WHEN out_date <= DATE '2022-05-01' THEN '출고완료'
WHEN out_date > DATE '2022-05-01' THEN '출고대기'
ELSE '출고미정'
END AS '출고여부'
FROM food_order
ORDER BY order_id
-- Oracle
SELECT order_id, product_id, TO_CHAR(out_date, 'YYYY-MM-DD') AS out_date,
CASE
WHEN out_date <= DATE '2022-05-01' THEN '출고완료'
WHEN out_date > DATE '2022-05-01' THEN '출고대기'
ELSE '출고미정'
END AS 출고여부
FROM food_order
ORDER BY order_id
- Oracle에서는 ' '는 문자열, " "는 컬럼명 또는 별칭으로 쓴다. 그래서 '출고여부'는 오류가 발생한다.
-- Oracle
SELECT
history_id, car_id,
TO_CHAR(start_date, 'YYYY-MM-DD') AS START_DATE,
TO_CHAR(end_date, 'YYYY-MM-DD') AS END_DATE,
CASE
WHEN end_date - start_date + 1 >= 30 THEN '장기 대여'
ELSE '단기 대여'
END AS RENT_TYPE
FROM car_rental_company_rental_history
WHERE start_date >= DATE '2022-09-01'
AND start_date < DATE '2022-10-01'
ORDER BY history_id DESC
-- MySQL
SELECT
history_id, car_id,
DATE_FORMAT(start_date, '%Y-%m-%d') AS START_DATE,
DATE_FORMAT(end_date, '%Y-%m-%d') AS END_DATE,
CASE
WHEN DATEDIFF(end_date, start_date) + 1 >= 30 THEN '장기 대여'
ELSE '단기 대여'
END AS RENT_TYPE
FROM car_rental_company_rental_history
WHERE start_date >= DATE '2022-09-01'
AND start_date < DATE '2022-10-01'
ORDER BY history_id DESC
- 날짜 계산 시, 2022-09-01 ~ 2022-09-30이 실제로는 30일이지만,
- MySQL의 DATEDIFF('09-30','09-01') = 29일이 된다.
- Oralce 경우에는 빼기가 가능, MySQL은 DATEDIFF()을 사용해야한다.
자동차 대여 기록 별 대여 금액 구하기
CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '트럭'인 자동차의 대여 기록에 대해서 대여 기록 별로 대여 금액(컬럼명: FEE)을 구하여 대여 기록 ID와 대여 금액 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 대여 기록 ID를 기준으로 내림차순 정렬해주세요.
-- Oracle
with h as (
select
history_id,
car_id,
(end_date - start_date + 1) as days
from car_rental_company_rental_history
),
truck as (
select car_id, daily_fee
from car_rental_company_car
where car_type = '트럭'
),
fee_base as (
select
h.history_id,
h.car_id,
h.days,
t.daily_fee,
case
when h.days >= 90 then '90일 이상'
when h.days >= 30 then '30일 이상'
when h.days >= 7 then '7일 이상'
else null
end as duration_type
from h
join truck t on t.car_id = h.car_id
)
select
f.history_id,
trunc(
f.daily_fee * f.days *
(100 - nvl(p.discount_rate, 0)) / 100
, 0) as fee
from fee_base f
left join car_rental_company_discount_plan p
on p.car_type = '트럭'
and p.duration_type = f.duration_type
order by fee desc, f.history_id desc;
-- MySQL
WITH history AS (
SELECT
history_id,
car_id,
DATEDIFF(end_date, start_date) + 1 AS rent_days,
CASE
WHEN DATEDIFF(end_date, start_date) + 1 >= 90 THEN '90일 이상'
WHEN DATEDIFF(end_date, start_date) + 1 >= 30 THEN '30일 이상'
WHEN DATEDIFF(end_date, start_date) + 1 >= 7 THEN '7일 이상'
ELSE NULL
END AS duration_type
FROM car_rental_company_rental_history
),
car AS (
SELECT car_id, car_type, daily_fee
FROM car_rental_company_car
WHERE car_type = '트럭'
)
SELECT
h.history_id,
ROUND(
c.daily_fee * h.rent_days * (100 - IFNULL(p.discount_rate, 0)) / 100
, 0) AS fee
FROM history h
JOIN car c
ON c.car_id = h.car_id
LEFT JOIN car_rental_company_discount_plan p
ON p.car_type = c.car_type
AND p.duration_type = h.duration_type
ORDER BY fee DESC, h.history_id DESC;
자동차 평균 대여 기간 구하기
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 평균 대여 기간이 7일 이상인 자동차들의 자동차 ID와 평균 대여 기간(컬럼명: AVERAGE_DURATION) 리스트를 출력하는 SQL문을 작성해주세요. 평균 대여 기간은 소수점 두번째 자리에서 반올림하고, 결과는 평균 대여 기간을 기준으로 내림차순 정렬해주시고, 평균 대여 기간이 같으면 자동차 ID를 기준으로 내림차순 정렬해주세요.
-- MySQL
WITH history AS (
SELECT history_id, DATEDIFF(end_date, start_date) + 1 AS days
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
)
SELECT a.car_id, ROUND(AVG(h.days), 1) AS AVERAGE_DURATION
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY a
JOIN history h
ON a.history_id = h.history_id
GROUP BY a.car_id
HAVING AVG(h.days) >= 7
ORDER BY AVERAGE_DURATION DESC, a.car_id DESC
-- Oracle
SELECT
car_id,
TO_CHAR(ROUND(AVG(end_date - start_date + 1), 1), 'FM99990.0')
AS AVERAGE_DURATION
FROM car_rental_company_rental_history
GROUP BY car_id
HAVING ROUND(AVG(end_date - start_date + 1), 1) >= 7
ORDER BY ROUND(AVG(end_date - start_date + 1), 1) DESC, car_id DESC
특정 옵션이 포함된 자동차 리스트 구하기
CAR_RENTAL_COMPANY_CAR 테이블에서 '네비게이션' 옵션이 포함된 자동차 리스트를 출력하는 SQL문을 작성해주세요. 결과는 자동차 ID를 기준으로 내림차순 정렬해주세요.
SELECT *
FROM car_rental_company_car
WHERE options LIKE '%네비게이션%'
ORDER BY car_id DESC
취소되지 않은 진료 예약 조회하기
PATIENT, DOCTOR 그리고 APPOINTMENT 테이블에서 2022년 4월 13일 취소되지 않은 흉부외과(CS) 진료 예약 내역을 조회하는 SQL문을 작성해주세요. 진료예약번호, 환자이름, 환자번호, 진료과코드, 의사이름, 진료예약일시 항목이 출력되도록 작성해주세요. 결과는 진료예약일시를 기준으로 오름차순 정렬해주세요.
SELECT a.apnt_no, p.pt_name, p.pt_no, a.mcdp_cd, d.dr_name, a.apnt_ymd
FROM appointment a
JOIN doctor d
ON a.mddr_id = d.dr_id
AND (a.apnt_cncl_yn = 'N' OR a.apnt_cncl_yn IS NULL)
AND UPPER(a.mcdp_cd) = 'CS'
JOIN patient p
ON p.pt_no = a.pt_no
WHERE a.apnt_ymd >= DATE '2022-04-13'
AND a.apnt_ymd < DATE '2022-04-14'
ORDER BY a.apnt_ymd
루시와 엘라 찾기
동물 보호소에 들어온 동물 중 이름이 Lucy, Ella, Pickle, Rogan, Sabrina, Mitty인 동물의 아이디와 이름, 성별 및 중성화 여부를 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.
SELECT animal_id, name, sex_upon_intake
FROM animal_ins
WHERE name IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
ORDER BY animal_id
이름에 el이 들어가는 동물 찾기
동물 보호소에 들어온 동물 이름 중, 이름에 "EL"이 들어가는 개의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 이름 순으로 조회해주세요. 단, 이름의 대소문자는 구분하지 않습니다.
SELECT animal_id, name
FROM animal_ins
WHERE LOWER(name) LIKE '%el%'
AND LOWER(animal_type) = 'dog'
ORDER BY name
중성화 여부 파악하기
중성화된 동물은 SEX_UPON_INTAKE 컬럼에 'Neutered' 또는 'Spayed'라는 단어가 들어있습니다. 동물의 아이디와 이름, 중성화 여부를 아이디 순으로 조회하는 SQL문을 작성해주세요. 이때 중성화가 되어있다면 'O', 아니라면 'X'라고 표시해주세요.
SELECT animal_id, name,
CASE
WHEN LOWER(sex_upon_intake) LIKE 'neutered%'
OR LOWER(sex_upon_intake) LIKE 'spayed%' THEN 'O'
ELSE 'X'
END AS 중성화
FROM animal_ins
ORDER BY animal_id
오랜 기간 보호한 동물(2)
입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 기간이 긴 순으로 조회해야 합니다.
SELECT x.animal_id, x.name
FROM (
SELECT i.animal_id, i.name, RANK() OVER(ORDER BY o.datetime - i.datetime DESC) AS rnk
FROM animal_ins i
JOIN animal_outs o
ON i.animal_id = o.animal_id
) x
WHERE x.rnk <= 2
ORDER BY x.rnk
카테고리 별 상품 개수 구하기
PRODUCT 테이블에서 상품 카테고리 코드(PRODUCT_CODE 앞 2자리) 별 상품 개수를 출력하는 SQL문을 작성해주세요. 결과는 상품 카테고리 코드를 기준으로 오름차순 정렬해주세요.
SELECT SUBSTR(product_code, 1, 2), COUNT(*)
FROM product
GROUP BY SUBSTR(product_code, 1, 2)
ORDER BY SUBSTR(product_code, 1, 2)
DATETIME에서 DATE로 형 변환
ANIMAL_INS 테이블에 등록된 모든 레코드에 대해, 각 동물의 아이디와 이름, 들어온 날짜1를 조회하는 SQL문을 작성해주세요. 이때 결과는 아이디 순으로 조회해야 합니다.
-- MySQL
SELECT animal_id, name, DATE_FORMAT(datetime, '%Y-%m-%d')
FROM animal_ins
ORDER BY animal_id
-- Oracle
SELECT animal_id, name, TO_CHAR(datetime, 'YYYY-MM-DD')
FROM animal_ins
ORDER BY animal_id
연도 별 평균 미세먼지 농도 조회하기
AIR_POLLUTION 테이블에서 수원 지역의 연도 별 평균 미세먼지 오염도와 평균 초미세먼지 오염도를 조회하는 SQL문을 작성해주세요. 이때, 평균 미세먼지 오염도와 평균 초미세먼지 오염도의 컬럼명은 각각 PM10, PM2.5로 해 주시고, 값은 소수 셋째 자리에서 반올림해주세요. 결과는 연도를 기준으로 오름차순 정렬해주세요.
SELECT EXTRACT(YEAR FROM ym) AS year,
ROUND(AVG(pm_val1), 2) AS "pm10",
ROUND(AVG(pm_val2), 2) AS "pm2.5"
FROM air_pollution
WHERE location2 = '수원' AND location1 = '경기도'
GROUP BY EXTRACT(YEAR FROM ym)
ORDER BY EXTRACT(YEAR FROM ym)
한 해에 잡은 물고기 수 구하기
FISH_INFO 테이블에서 2021년도에 잡은 물고기 수를 출력하는 SQL 문을 작성해주세요. 이 때 컬럼명은 'FISH_COUNT' 로 지정해주세요.
SELECT COUNT(*) AS fish_count
FROM fish_info
WHERE EXTRACT(YEAR FROM time) = 2021
GROUP BY EXTRACT(YEAR FROM time)
분기별 분화된 대장균의 개체 수 구하기
각 분기(QUARTER)별 분화된 대장균의 개체의 총 수(ECOLI_COUNT)를 출력하는 SQL 문을 작성해주세요. 이때 각 분기에는 'Q' 를 붙이고 분기에 대해 오름차순으로 정렬해주세요. 대장균 개체가 분화되지 않은 분기는 없습니다.
-- MySQL
SELECT
CONCAT(QUARTER(DIFFERENTIATION_DATE), 'Q') AS QUARTER,
COUNT(ID) AS ECOLI_COUNT
FROM ECOLI_DATA
GROUP BY QUARTER
ORDER BY QUARTER ASC;
- QUARTER는 년도 상관 없이 1~4 반환
-- Oracle
SELECT
TO_CHAR(DIFFERENTIATION_DATE, 'Q') || 'Q' AS QUARTER,
COUNT(ID) AS ECOLI_COUNT
FROM ECOLI_DATA
GROUP BY TO_CHAR(DIFFERENTIATION_DATE, 'Q')
ORDER BY QUARTER ASC;
MySQL
분기
quarter(date)
주차
week(date)
요일
dayofweek(date) -- 1~7
weekday(date) -- 0~6
분기 + 연도
concat(year(date), '-Q', quarter(date))
Oracle
주차
to_char(date, 'WW')
to_char(date, 'IW') -- ISO week
요일
to_char(date, 'D')
to_char(date, 'DY')
to_char(date, 'DAY')
QUARTER 대신 쓸 수 있는 분기 직접 계산:
case
when month(date) between 1 and 3 then 1
when month(date) between 4 and 6 then 2
when month(date) between 7 and 9 then 3
else 4
end
TO_CHAR 포맷 옵션 (Oracle)
연도
| YYYY | 4자리 연도 | 2024 |
| YY | 뒤 2자리 | 24 |
to_char(date,'YYYY')
월
| MM | 숫자 월 (01~12) |
| MON | 월 약어 (JAN) |
| MONTH | 월 전체 이름 |
to_char(date,'MM')
일
| DD | 일 (01~31) |
| DDD | 1년 중 몇 번째 날 |
분기
| Q | 분기 (1~4) |
to_char(date,'Q')
시간
| HH24 | 24시간 |
| HH | 12시간 |
| MI | 분 |
| SS | 초 |
to_char(sysdate,'HH24:MI:SS')
요일
| D | 요일 숫자 |
| DY | 요일 약어 |
| DAY | 요일 이름 |
to_char(date,'DAY')
날짜 포맷 만들기
to_char(date,'YYYY-MM-DD')
to_char(date,'YYYY/MM/DD')
to_char(date,'YYYY-MM')
NTILE과 QUARTER 차이
QUARTER
- 달력 기준
- 1~3월 = 1Q
- 고정
NTILE(4)
- 데이터 분포 기준
- 개수로 4등분
- 달력과 무관
ntile(4) over(order by sales)
매출 기준 상위 25% 같은 개념.
연도 + 분기 Oracle
to_char(date,'YYYY') || '-Q' || to_char(date,'Q')
MySQL
concat(year(date), '-Q', quarter(date))
'Database > SQL' 카테고리의 다른 글
| ALTER, DROP, TRUNCATE (0) | 2026.02.10 |
|---|---|
| CREATE (0) | 2026.02.10 |
| GROUP BY (0) | 2026.02.09 |
| JOIN (0) | 2026.02.08 |
| SUM, MAX, MIN (0) | 2026.02.07 |