SELECT ROUND(AVG(DAILY_FEE)) AS 'AVERAGE_FEE'
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE='SUV'
GROUP BY CAR_TYPE;
ROUND(숫자, 자릿수)
SELECT MEMBER_ID, MEMBER_NAME, GENDER, DATE_FORMAT(DATE_OF_BIRTH, '%Y-%m-%d') AS 'DATE_OF_BIRTH'
FROM MEMBER_PROFILE
WHERE MONTH(DATE_OF_BIRTH)=3 AND GENDER='W' AND TLNO IS NOT NULL
ORDER BY MEMBER_ID;
MONTH(날짜)=3
⚠️DATE_FORMAT
으로 날짜 출력 형식 맞추기
SELECT *
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
ORDER BY
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*)>=2
ORDER BY USER_ID, PRODUCT_ID DESC;
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS 'SALES_DATE', PRODUCT_ID, USER_ID, SALES_AMOUNT
FROM ONLINE_SALE
WHERE SALES_DATE LIKE '2022-03%'
UNION ALL
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS 'SALES DATE', PRODUCT_ID, NULL AS 'USER_ID', SALES_AMOUNT
FROM OFFLINE_SALE
WHERE SALES_DATE LIKE '2022-03%'
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;
UNION
(중복제외), UNION ALL
(중복포함)SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION != 'Aged'
order by ANIMAL_ID
!=
SELECT ANIMAL_ID, NAME, DATETIME
FROM ANIMAL_INS
ORDER BY NAME, DATETIME DESC -- 이름순으로 정렬, 이름 같으면 날짜 역순으로 정렬하라는 의미
SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1
LIMIT
SELECT ITEM_ID, ITEM_NAME, RARITY
FROM ITEM_INFO
WHERE ITEM_ID IN (SELECT T.ITEM_ID
FROM ITEM_INFO I, ITEM_TREE T
WHERE RARITY = 'RARE' AND PARENT_ITEM_ID = I.ITEM_ID)
ORDER BY ITEM_ID DESC;
IN
단일행은 =
SELECT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPERS
WHERE SKILL_CODE & (SELECT SUM(CODE)
FROM SKILLCODES
WHERE NAME IN ('Python', 'C#'))
ORDER BY ID;
&
: 특정값을 포함하는 경우 찾을 때 //각 비트가 전부 1일 때만 1 반환SELECT COUNT(*) AS 'count'
FROM ANIMAL_INS
COUNT
집계함수 사용SELECT COUNT(DISTINCT NAME)
FROM ANIMAL_INS
DISTINCT
SELECT A.AUTHOR_ID, AUTHOR_NAME, CATEGORY, SUM(SALES*PRICE) AS 'TOTAL_SALES'
FROM BOOK_SALES BS LEFT JOIN BOOK B ON BS.BOOK_ID=B.BOOK_ID
LEFT JOIN AUTHOR A ON B.AUTHOR_ID=A.AUTHOR_ID
WHERE SALES_DATE LIKE '2022-01%'
GROUP BY AUTHOR_ID, CATEGORY
ORDER BY AUTHOR_ID, CATEGORY DESC;
다중테이블 JOIN
: 어렵게 생각할 필요없이 규칙 맞춰서 연달아 JOIN 해주면 됨SELECT MONTH(START_DATE) AS 'MONTH', CAR_ID, COUNT(*) AS 'RECORDS'
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE CAR_ID IN (SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) IN (8, 9, 10)
GROUP BY CAR_ID
HAVING COUNT(*) >= 5)
AND MONTH(START_DATE) IN (8, 9, 10)
GROUP BY MONTH(START_DATE), CAR_ID
HAVING COUNT(*) > 0
ORDER BY MONTH(START_DATE), CAR_ID DESC;
대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요.
⚠️문제를 잘 읽자... 서브쿼리 잘 짜놓고 대여 종료일을 기준으로 풀어서 틀림 ;
SELECT CAR_ID, IF(SUM(IF('2022-10-16' BETWEEN START_DATE AND END_DATE, 1, 0))>0, '대여중', '대여 가능') AS 'AVAILABILITY'
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;
날짜 BETWEEN 시작범위 AND 종료범위
SELECT ANIMAL_TYPE, COUNT(*) AS 'count'
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE
GROUP BY
: 특정 column을 기준으로 그룹화시킴SELECT NAME, COUNT(*) AS 'COUNT'
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
GROUP BY NAME
HAVING COUNT(*) >= 2
ORDER BY NAME
동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성해주세요.
이때 결과는 이름이 없는 동물은 집계에서 제외하며,
결과는 이름 순으로 조회해주세요.
⚠️테스트 결과값이 맞게 나왔어도 문제 조건 전부 처리해줘야 함
HAVING
: 집계함수로 조건비교 할 때 (WHERE은 불가능)WHERE COLUMN명 IS NOT NULL
SELECT HOUR(DATETIME) AS 'HOUR', COUNT(*) AS 'COUNT'
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) >= 9 AND HOUR(DATETIME) <= 19
GROUP BY HOUR
ORDER BY HOUR
날짜 데이터에서 일부를 추출해야 하는데 방법을 몰라서 솔루션 찾음
HOUR
함수 : DATETIME에서 hour 추출SELECT YEAR(SALES_DATE) AS 'YEAR', MONTH(SALES_DATE) AS 'MONTH', GENDER, COUNT(DISTINCT INFO.USER_ID) AS 'USERS'
FROM USER_INFO INFO JOIN ONLINE_SALE SALE ON INFO.USER_ID=SALE.USER_ID
WHERE GENDER IS NOT NULL
GROUP BY YEAR, MONTH, GENDER
ORDER BY YEAR, MONTH, GENDER;
년, 월, 성별 별로 상품을 구매한 회원수를 집계하는 SQL문을 작성해주세요.
➡️GROUP BY YEAR, MONTH, GENDER
➡️COUNT(USER_ID)
동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.
➡️중복 제거 : COUNT( DISTINCT USER_ID)
⚠️잘 보면 문제에 답이 있다.
⚠️JOIN 할 때 뒤에 ON A.ID=B.ID
까먹지 말기
count가 0인 값도 테이블에 포함해야 하는데 방법을 몰라서 솔루션 찾음
#step 1
SET @HOUR := -1;
SELECT (@HOUR := @HOUR+1) AS HOUR
FROM ANIMAL_OUTS
WHERE @HOUR < 23 -- 23 미만일 때까지 대입되어 HOUR 22일 때 멈추고, 22는 23이 됨
SET
함수 사용@변수명
:=
#step 2
SET @HOUR := -1;
SELECT (@HOUR := @HOUR+1) AS HOUR, (SELECT COUNT(*)
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) = @HOUR) AS COUNT
FROM ANIMAL_OUTS
WHERE @HOUR < 23
WHERE HOUR(DATETIME) = @HOUR
SELECT TRUNCATE(PRICE, -4) AS 'PRICE_GROUP', COUNT(PRODUCT_ID) AS 'PRODUCTS'
FROM PRODUCT
GROUP BY PRICE_GROUP
ORDER BY PRICE_GROUP;
TRUNCATE(PRICE, -4)
로 표현 가능TRUNCATE(숫자, 버릴 자릿 수)
SELECT ANIMAL_TYPE, IFNULL(NAME, 'No name') AS NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
IFNULL
함수 : column 값이 null일 때, 다른 값을 반환하도록SELECT IFNULL(column명, '대체할 값')
SELECT ITEM_ID, ITEM_NAME, RARITY
FROM ITEM_INFO
WHERE ITEM_ID NOT IN (SELECT PARENT_ITEM_ID
FROM ITEM_TREE
WHERE PARENT_ITEM_ID IS NOT NULL)
ORDER BY ITEM_ID DESC;
NOT IN
조건 : NULL값이 포함되는 경우, 값이 출력되지 않음 ➡️조회 칼럼에 IS NOT NULL
조건 줘야 함SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS LEFT OUTER JOIN ANIMAL_INS INS ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE INS.ANIMAL_ID IS NULL
ORDER BY OUTS.ANIMAL_ID
JOIN
: TABLE_A A JOIN TABLE_B B ON A.KEY 값=B.KEY 값
- JOIN : key값이 같은 데이터만 가져옴
- LEFT OUTER JOIN (좌측 정보 손실 방지) : 좌측 테이블 값 전부 나타내고, key값 다르면 null로 표시
- RIGHT OUTER JOIN (우측 정보 손실 방지) : 우측 테이블 값 전부 나타내고, key값 다르면 null로 표시
- FULL OUTER JOIN (양쪽 전부 정보 손실 방지) : 양쪽 테이블 값 전부 나타내고, key값 다르면 null로 표시
LEFT OUTER JOIN
사용SELECT INS.ANIMAL_ID, INS.ANIMAL_TYPE, INS.NAME
FROM ANIMAL_INS INS JOIN ANIMAL_OUTS OUTS ON INS.ANIMAL_ID = OUTS.ANIMAL_ID
WHERE INS.SEX_UPON_INTAKE LIKE 'Intact %' AND (OUTS.SEX_UPON_OUTCOME LIKE 'Spayed %' OR OUTS.SEX_UPON_OUTCOME LIKE 'Neutered %')
ORDER BY INS.ANIMAL_ID
like
WITH RENT_INFO AS
(SELECT HISTORY_ID, DATEDIFF(END_DATE, START_DATE)+1 AS 'RENT_DAYS', DAILY_FEE, CAR_TYPE,
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 ''
END AS 'DURATION_TYPE'
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H JOIN CAR_RENTAL_COMPANY_CAR C ON H.CAR_ID=C.CAR_ID
WHERE CAR_TYPE='트럭')
SELECT RENT_INFO.HISTORY_ID, ROUND(RENT_INFO.DAILY_FEE * RENT_INFO.RENT_DAYS * (100-IFNULL(PLAN.DISCOUNT_RATE, 0))/100) AS 'FEE'
FROM RENT_INFO LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN AS PLAN ON PLAN.DURATION_TYPE=RENT_INFO.DURATION_TYPE AND PLAN.CAR_TYPE=RENT_INFO.CAR_TYPE
ORDER BY FEE DESC, HISTORY_ID DESC;
1번 자동차 대여 기간이 90일 이상 일 때는 15% 할인 / 30일 : 10% / 7일 : 5% 중에 해당하는 경우로 가격을 구해야하는데 테이블 조인하니까 각각의 자동차에 3가지 데이터가 나왔다.
➡️임시 테이블 만들어서 '90일 이상' 이 부분을 join 조건으로 만들어줘야 함
⚠️
5000원에 5% 할인된 금액 :5000 * 0.05
=5000 * (100 - DISCOUNT_RATE / 100)
➡️NULL값을 100으로 나누면 안되니까IFNULL함수
로 처리해줘야 함
WITH 가상테이블명 AS
(SELECT
FROM
WHERE)
SELECT NAME,
CASE
WHEN point > 1000 THEN '상'
WHEN point > 500 THEN '중'
ELSE '하'
END AS 'LEVEL'
FROM TABLE
SELECT CAR_ID, ROUND(AVG(DATEDIFF(END_DATE, START_DATE)+1), 1) AS 'AVERAGE_DURATION'
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
HAVING AVERAGE_DURATION >= 7
ORDER BY AVERAGE_DURATION DESC, CAR_ID DESC;
DATEDIFF
➡️평균 구하기 : AVG
➡️반올림 : ROUND
SELECT USER_ID, NICKNAME, CONCAT(CITY, ' ', STREET_ADDRESS1, ' ', STREET_ADDRESS2) AS '전체주소', CONCAT(SUBSTRING(TLNO, 1, 3), '-', SUBSTRING(TLNO, 4, 4), '-', SUBSTRING(TLNO, 8, 4)) AS '전화번호'
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;
CONCAT(first_name, ' ', last_name)
SUBSTRING(문자열, 시작위치, 길이)
// SQL은 index 1부터 시작함// 서브쿼리 값 여러개
WHERE A.name IN (SELECT B.name
FROM 테이블
WHERE 조건)
// 서브쿼리 값 한개
WHERE A.name = (SELECT B.name
FROM 테이블
WHERE 조건)
SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
IN
➡️집합 개념SELECT ANIMAL_ID, NAME, IF(SEX_UPON_INTAKE LIKE 'Intact %', 'X', 'O') AS '중성화'
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
IF(조건, 참 일때의 값, 거짓일 때의 값)
➡️SELECT에서 사용SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_INS INS JOIN ANIMAL_OUTS OUTS ON INS.ANIMAL_ID = OUTS.ANIMAL_ID
ORDER BY OUTS.DATETIME - INS.DATETIME DESC -- 보호 기간이 긴 순서니까 DESC
LIMIT 2
SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME, '%Y-%m-%d') AS '날짜'
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
DATE_FORMAT(DATETIME, '%Y-%m-%d')
// 2018-01-22구분기호
년 : %Y(4자리 연도), %y(2자리 연도)
월 : %m
일 : %d
시 : %H(24시간), %h(12시간)
분 : %i
초 : %s