SELECT MEMBER_ID, MEMBER_NAME, GENDER ,
date_format(DATE_OF_BIRTH, "%Y-%m-%d") AS DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE TLNO IS NOT NULL &&
GENDER = 'W' &&
date_format(DATE_OF_BIRTH, '%m') = 3
ORDER BY MEMBER_ID ASC
SELECT NAME, COUNT(*) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME
SELECT COUNT(ANIMAL_ID)
FROM ANIMAL_INS;
SELECT COUNT(*)
FROM (
SELECT NAME
FROM ANIMAL_INS
GROUP BY NAME
) AS A
WHERE NAME IS NOT NULL
SELECT *
FROM FOOD_PRODUCT
ORDER BY PRICE DESC
LIMIT 1;
# 서브쿼리로
SELECT *
FROM FOOD_PRODUCT
WHERE PRICE = (SELECT MAX(F.PRICE) from FOOD_PRODUCT F)
SELECT HOUR(DATETIME) AS HOUR, COUNT(DATETIME) AS COUNT
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) BETWEEN 9 AND 19
GROUP BY HOUR
ORDER BY HOUR
SELECT SUBSTRING(PRODUCT_CODE,1,2) AS CATEGORY,
COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY CATEGORY
ORDER BY CATEGORY;
SELECT MCDP_CD AS '진료과 코드',
COUNT(APNT_NO) AS '5월예약건수'
FROM APPOINTMENT
WHERE APNT_YMD LIKE '2022-05%'
GROUP BY MCDP_CD
ORDER BY 2, 1;
SELECT (PRICE - PRICE%10000) AS PRICE_GROUP,
COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY PRICE_GROUP
ORDER BY PRICE_GROUP;
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT (USER_ID) > 1
ORDER BY 1, 2 DESC
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
SELECT I.NAME, I.DATETIME
FROM ANIMAL_INS AS I
LEFT JOIN ANIMAL_OUTS AS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE O.DATETIME IS NULL
ORDER BY DATETIME
LIMIT 3;
SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS AS I
JOIN ANIMAL_OUTS AS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.SEX_UPON_INTAKE LIKE 'INTACT%'
&& O.SEX_UPON_OUTCOME NOT LIKE 'INTACT%'
ORDER BY I.ANIMAL_ID
# LOCATE 사용시
ELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS AS I
JOIN ANIMAL_OUTS AS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE LOCATE('intact', I.SEX_UPON_INTAKE) >= 1
&& LOCATE('intact', O.SEX_UPON_OUTCOME) = 0
SELECT B.CATEGORY, SUM(S.SALES) AS TOTAL_SALES
FROM BOOK_SALES AS S
JOIN BOOK AS B
ON S.BOOK_ID = B.BOOK_ID
WHERE S.SALES_DATE LIKE '2022-01%'
GROUP BY B.CATEGORY
ORDER BY B.CATEGORY
;
WITH B AS (
SELECT WRITER_ID
, SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD
WHERE STATUS IN ('DONE')
GROUP BY WRITER_ID
)
SELECT U.USER_ID, U.NICKNAME, B.TOTAL_SALES
FROM B
JOIN USED_GOODS_USER AS U
ON B.WRITER_ID = U.USER_ID
WHERE TOTAL_SALES >= 700000
ORDER BY TOTAL_SALES;
SELECT U.USER_ID, U.NICKNAME, SUM(B.PRICE)TOTAL_SALES
FROM USED_GOODS_BOARD AS B
JOIN USED_GOODS_USER AS U
ON B.WRITER_ID = U.USER_ID
WHERE B.STATUS = 'DONE'
GROUP BY U.USER_ID
HAVING TOTAL_SALES >= 700000
ORDER BY TOTAL_SALES;
식품분류별 가장 비싼 식품의 정보 조회하기와 비슷
# 다중 조건 IN (서브쿼리)
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) IN (SELECT FOOD_TYPE, MAX(FAVORITES)
FROM REST_INFO
GROUP BY FOOD_TYPE
)
ORDER BY FOOD_TYPE DESC
;
# JOIN
WITH FAV AS (
SELECT FOOD_TYPE, MAX(FAVORITES) AS FAVORITES
FROM REST_INFO
GROUP BY FOOD_TYPE
)
SELECT R.FOOD_TYPE, R.REST_ID, R.REST_NAME, R.FAVORITES
FROM REST_INFO AS R
JOIN FAV
ON FAV.FOOD_TYPE = R.FOOD_TYPE
&& FAV.FAVORITES = R.FAVORITES
ORDER BY FOOD_TYPE DESC;
테이블을 이중으로 만들어 비교를 해야 하는 이유
max값은 제대로 가져오는데 다른 식당 정보(REST_NAME)를 다른 row에서 가져올 수 있음!
FOOD_TYPE REST_ID REST_NAME FAVORITES
한식 00001 은돼지식당 734
중식 00015 만정 20
일식 00002 하이가쯔네 230
양식 00003 따띠따띠뜨 102
분식 00008 애플우스 151
-> 한 겹?으로 돌린경우 일식의 식당 정보가 틀림
FOOD_TYPE REST_ID REST_NAME FAVORITES
한식 00001 은돼지식당 734
중식 00015 만정 20
일식 00004 스시사카우스 230
양식 00003 따띠따띠뜨 102
분식 00008 애플우스 151
-> 서브쿼리로 돌린경우 알맞은 식당 정보
table1: 음식 종류 당 최다 즐겨찾기
table2: 모든 정보가 다 담긴 테이블
SELECT R.REST_ID, I.REST_NAME, I.FOOD_TYPE, I.FAVORITES,
I.ADDRESS, ROUND(AVG(R.REVIEW_SCORE),2) AS SCORE
FROM REST_INFO AS I
JOIN REST_REVIEW AS R
ON I.REST_ID = R.REST_ID
WHERE ADDRESS LIKE '서울%'
GROUP BY I.REST_ID, I.REST_NAME, I.FOOD_TYPE, I.FAVORITES,
I.ADDRESS
ORDER BY SCORE DESC, FAVORITES DESC ;
계속 틀리길래 왜이럴까 하고 '%서울%' 에서 '서울%'로 바꿨더니 맞았다. 결과는 어떻게 하든 똑같았는데🤔 대한민국으로 시작할 수도 있지 않나유
3번째에서 반올림하면 2번째 자리까지 표시된다. 그래서 ROUND(,2) 로 해야함
LIKE Operator Description
% 문자 혹은 숫자
_ 자리값
'a%' start with "a"
'%a' end with "a"
'%or%' "or" in any position
'_r%' "r" in the second position
'a_%' start with "a" and are at least 2 characters in length
'a__%' start with "a" and are at least 3 characters in length
'a%o' start with "a" and ends with "o"
WITH MILK AS (
SELECT CART_ID
FROM CART_PRODUCTS
WHERE NAME = 'Milk'
)
SELECT DISTINCT YOG.CART_ID
FROM CART_PRODUCTS AS YOG
JOIN MILK
ON MILK.CART_ID = YOG.CART_ID
WHERE NAME = 'YOGURT'
ORDER BY CART_ID
# 합쳐서 이렇게 쓸 수도 있다
SELECT DISTINCT YOG.CART_ID
FROM CART_PRODUCTS MILK
JOIN CART_PRODUCTS YOG
ON A.CART_ID = B.CART_ID
WHERE MILK.NAME = 'Milk'
&& YOG.NAME = 'Yogurt'
ORDER BY MILK.CART_ID;
WITH AP AS
(
SELECT A.APNT_NO, P.PT_NAME, P.PT_NO, A.MCDP_CD, A.APNT_YMD, A.MDDR_ID
FROM APPOINTMENT AS A
INNER JOIN PATIENT AS P
ON A.PT_NO = P.PT_NO
WHERE A.APNT_YMD LIKE '2022-04-13%'
&& A.APNT_CNCL_YN = 'N'
)
SELECT AP.APNT_NO, AP.PT_NAME, AP.PT_NO, AP.MCDP_CD,
D.DR_NAME, AP.APNT_YMD
FROM AP
JOIN DOCTOR AS D
ON D.DR_ID = AP.MDDR_ID
ORDER BY APNT_YMD;
SELECT CAR_ID,
CASE
WHEN MAX('2022-10-16' BETWEEN START_DATE AND END_DATE)
THEN '대여중'
ELSE '대여 가능'
END AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY 1
ORDER BY 1 DESC;
# 서브쿼리 이용
WITH CAR AS (
SELECT CAR_ID,
CASE
WHEN START_DATE <= '2022-10-16' AND '2022-10-16' <= END_DATE
THEN 1 ELSE 0
END A
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID, A
)
SELECT H.CAR_ID,
CASE
WHEN MAX(CAR.A) = 1
THEN '대여중' ELSE '대여 가능'
END as AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H
JOIN CAR
ON CAR.CAR_ID = H.CAR_ID
GROUP BY 1
ORDER BY 1 DESC;
SELECT A.AUTHOR_ID, A.AUTHOR_NAME, B.CATEGORY,
SUM(S.SALES * B.PRICE) AS TOTAL_SALES
FROM BOOK_SALES AS S
JOIN BOOK AS B ON S.book_id = B.book_id
JOIN AUTHOR A ON B.author_id = A.author_id
WHERE SALES_DATE LIKE '2022-01%'
GROUP BY 1, 3
ORDER BY 1, 3 DESC
SUM(S.SALES) * B.PRICE AS TOTAL_SALES ❌
AUTHOR_ID AUTHOR_NAME CATEGORY TOTAL_SALES
1 홍길동 인문 561000
1 홍길동 경제 1212000
2 김영호 소설 450000
3 김수진 생활 817000
3 김수진 기술 1661000
SUM(S.SALES * B.PRICE) AS TOTAL_SALES ⭕️
AUTHOR_ID AUTHOR_NAME CATEGORY TOTAL_SALES
1 홍길동 인문 561000
1 홍길동 경제 1107000
2 김영호 소설 450000
3 김수진 생활 817000
3 김수진 기술 1523000
왜 자꾸 틀리는지 답답했는데 괄호가 문제였다..
기호로 하면 대충 (a+b) * c
ac + bc 일텐데 값이 다르게 나온다..!
SELECT
MONTH(RT1.START_DATE) AS 'MONTH',
RT1.CAR_ID,
COUNT(RT2.HISTORY_ID) AS 'RECORDS'
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY RT1
JOIN (
SELECT *
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE YEAR(START_DATE) = '2022'
AND MONTH(START_DATE) BETWEEN 8 AND 10
GROUP BY CAR_ID
HAVING COUNT(HISTORY_ID) >= 5
) RT2 ON RT1.CAR_ID = RT2.CAR_ID
WHERE MONTH(RT1.START_DATE) BETWEEN 8 AND 10
GROUP BY MONTH, RT1.CAR_ID
HAVING RECORDS > 0
ORDER BY MONTH ASC, RT1.CAR_ID DESC
WITH M AS ( # 최대 댓글 회원들을 알아내기 위한 쿼리
SELECT DISTINCT MEMBER_ID
FROM REST_REVIEW
GROUP BY MEMBER_ID
HAVING COUNT(MEMBER_ID) >= (
# 최고 빈도수를 알아내기 위한 쿼리
SELECT COUNT(MEMBER_ID) AS CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID
ORDER BY CNT DESC
LIMIT 1
)
)
SELECT P.MEMBER_NAME, R.REVIEW_TEXT,
DATE_FORMAT(R.REVIEW_DATE,'%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE AS P
NATURAL JOIN REST_REVIEW AS R
NATURAL JOIN M
ORDER BY 3, 2 ;
SELECT column_name(s)
FROM table1
WHERE condition1
UNION
SELECT column_name(s)
FROM table2
WHERE condition2;
WITH RECURSIVE FIVE AS(
SELECT 1 as NUM
# 셀렉트 문으로 초기값과 컬럼이름 명시
UNION
SELECT NUM+1
FROM FIVE
WHERE NUM < 5;
) # 1<= x <= 5
SELECT *
FROM FIVE;
# 내림차수로 하고 싶다면 order by desc
NUM
1
2
3
4
5
WITH RECURSIVE THREE AS(
SELECT 5 as NUM
UNION
SELECT NUM-1
FROM THREE
WHERE Mon > 1;
) # 3>= x >= 1
SELECT *
FROM THREE;
NUM
3
2
1
WITH RECURSIVE H AS(
SELECT 0 as HOURS
UNION
SELECT HOURS+1
FROM H
WHERE HOURS < 23
)
SELECT HOURS,
CASE
WHEN O.COUNT IS NULL
THEN 0
ELSE O.COUNT
END COUNT
FROM H
LEFT JOIN (
SELECT HOUR(DATETIME) AS HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM ANIMAL_OUTS
GROUP BY HOUR
) AS O
ON H.HOURS = O.HOUR
(
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE,
PRODUCT_ID, NULL AS USER_ID, SALES_AMOUNT
FROM OFFLINE_SALE
WHERE MONTH(SALES_DATE) = 3
)
UNION
(
SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') AS SALES_DATE,
PRODUCT_ID, USER_ID, SALES_AMOUNT
FROM ONLINE_SALE
WHERE MONTH(SALES_DATE) = 3
)
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;
WITH M21 AS (
SELECT *
FROM USER_INFO
WHERE YEAR(JOINED) = 2021
)
SELECT YEAR(SALES_DATE) AS YEAR,
MONTH(SALES_DATE) AS MONTH,
COUNT(DISTINCT USER_ID) AS PUCHASED_USERS,
ROUND( COUNT(DISTINCT USER_ID)
/ (SELECT COUNT(*) FROM M21), 1) AS RATIO
FROM ONLINE_SALE
JOIN M21 USING(USER_ID)
GROUP BY 2
ORDER BY 2;
YEAR MONTH PUCHASED_USERS M21 RATIO
2022 1 47 158 0.3
2022 2 40 158 0.3
2022 3 6 158 0.0
CONDITIONS
테이블 세개
CAR_RENTAL_COMPANY_CAR, CAR_RENTAL_COMPANY_RENTAL_HISTORY,
CAR_RENTAL_COMPANY_DISCOUNT_PLAN
자동차 종류가 '세단' 또는 'SUV' 인 자동차 중
2022년 11월 1일부터 2022년 11월 30일까지 대여 가능하고
-> NOT IN 11월 1일 이후 부터 빌리기 시작하거나 OR (11월 1일 이전에 빌려서) 11월 1일 이후에 반납하거나
30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차에 대해서
-> HAVING 으로 조건을 걸어준다. 집계함수를 사용하고 있기 때문
SELECT
자동차 ID, 자동차 종류, 대여 금액(컬럼명: FEE)
ORDER BY
SELECT N.CAR_ID, P.CAR_TYPE
, ROUND(C.DAILY_FEE * 30 * (100 - P.DISCOUNT_RATE)/100,0) AS FEE
FROM CAR_RENTAL_COMPANY_CAR AS C
JOIN (
SELECT DISTINCT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE CAR_ID NOT IN (
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE >= '2022-11-01'
|| END_DATE >= '2022-11-01'
)
) AS N USING (CAR_ID)
JOIN (
SELECT *
FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
WHERE DURATION_TYPE LIKE '30%'
) AS P USING (CAR_TYPE)
WHERE CAR_TYPE IN ('세단','SUV' )
HAVING FEE >= 500000 AND FEE < 2000000
ORDER BY 3 DESC, 2, 1 DESC;
CAR_ID CAR_TYPE FEE
3 세단 1518000
23 세단 1380000
WITH T AS (
SELECT *, COALESCE(DR, 0) AS DDR
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H
NATURAL JOIN (
SELECT *
, DATEDIFF(END_DATE, START_DATE)+1 AS DAYS
, CASE
WHEN DATEDIFF(END_DATE, START_DATE)+1 < 7 THEN 0
WHEN DATEDIFF(END_DATE, START_DATE)+1 < 30 THEN 1
WHEN DATEDIFF(END_DATE, START_DATE)+1 < 90 THEN 2
ELSE 3
END GR
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
NATURAL JOIN CAR_RENTAL_COMPANY_CAR AS C
WHERE C.CAR_TYPE = '트럭'
) AS C
LEFT JOIN (
SELECT DISCOUNT_RATE AS DR
, CASE
WHEN DURATION_TYPE LIKE '7%' THEN 1
WHEN DURATION_TYPE LIKE '3%' THEN 2
WHEN DURATION_TYPE LIKE '9%' THEN 3
END GR
FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
WHERE CAR_TYPE = '트럭'
) AS P USING(GR)
)
SELECT HISTORY_ID
, ROUND(DAYS * DAILY_FEE * (100 - DDR)/100, 0) AS FEE
FROM T
ORDER BY 2 DESC, 1 DESC
;
다음은 다른사람의 코드인데 셀렉트문 안에서 전처리하는 방법을 볼 수 있어서 가져왔다. 내 코드가 커진게 셀렉트 전처리 방법이 익숙하지 않아서 인것 같다.
SELECT
HISTORY_ID,
FLOOR(
DAILY_FEE
* (DATEDIFF(END_DATE, START_DATE)+1)
* (100 - COALESCE(
(
SELECT MAX(DISCOUNT_RATE)
FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN P
WHERE (
DATEDIFF(END_DATE, START_DATE)+1)
>=
CAST(REPLACE(DURATION_TYPE, '일 이상', '') AS SIGNED
)
&& CAR_TYPE = '트럭'
), 0)
)
/ 100
) AS FEE
FROM CAR_RENTAL_COMPANY_CAR R
JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY H
USING (CAR_ID)
WHERE CAR_TYPE = '트럭'
ORDER BY 2 DESC, 1 DESC;