다때려박아봣어요.
- 제가 푼 답
- 다른 분들 답 중 기록해두고 싶은 것
- 문제 푸는 포인트
등을 적어 두었습니다.
모든 문제가 있지는 않으며, 수정 중이라 부족한 부분이 많습니다.
문제 풀면서 바로바로 기록한 걸 아무런 검토없이 냅다 올려버려서 그렇습니다... 쫌만 봐주세요 🙏
친구가 스압주의 풀고 글을 쪼개라는데... 그냥 오른쪽 목차에서 찾아보셔요
* : 복습필수 (님들 말구 제 얘깁니다..)
FIRST_HALF
테이블은 아이스크림 가게의 상반기 주문 정보를 담은 테이블입니다.FIRST_HALF
테이블 구조는 다음과 같으며, SHIPMENT_ID
, FLAVOR
, TOTAL_ORDER
는 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 상반기 아이스크림 총주문량을 나타냅니다.
NAME | TYPE | NULLABLE |
---|---|---|
SHIPMENT_ID | INT(N) | FALSE |
FLAVOR | VARCHAR(N) | FALSE |
TOTAL_ORDER | INT(N) | FALSE |
FIRST_HALF
테이블이 다음과 같을 때
SHIPMENT_ID | FLAVOR | TOTAL_ORDER |
---|---|---|
101 | chocolate | 3200 |
102 | vanilla | 2800 |
103 | mint_chocolate | 1700 |
104 | caramel | 2600 |
105 | white_chocolate | 3100 |
106 | peach | 2450 |
107 | watermelon | 2150 |
108 | mango | 2900 |
109 | strawberry | 3100 |
110 | melon | 3150 |
111 | orange | 2900 |
112 | pineapple | 2900 |
SELECT flavor
FROM FIRST_HALF
ORDER BY total_order DESC, shipment_id
MEMBER_PROFILE
테이블입니다. MEMBER_PROFILE
테이블은 다음과 같으며 MEMBER_ID
, MEMBER_NAME
, TLNO
, GENDER
, DATE_OF_BIRTH
는 회원 ID, 회원 이름, 회원 연락처, 성별, 생년월일을 의미합니다.
Column name | Type | Nullable |
---|---|---|
MEMBER_ID | VARCHAR(100) | FALSE |
MEMBER_NAME | VARCHAR(50) | FALSE |
TLNO | VARCHAR(50) | TRUE |
GENDER | VARCHAR(1) | TRUE |
DATE_OF_BIRTH | DATE | TRUE |
MEMBER_PROFILE
테이블에서 생일이 3월인 여성 회원의 ID, 이름, 성별, 생년월일을 조회하는 SQL문을 작성해주세요. 이때 전화번호가 NULL인 경우는 출력대상에서 제외시켜 주시고, 결과는 회원ID를 기준으로 오름차순 정렬해주세요.MEMBER_PROFILE
테이블이 다음과 같을 때
MEMBER_ID | MEMBER_NAME | TLNO | GENDER | DATE_OF_BIRTH |
---|---|---|---|---|
jiho92@naver.com | 이지호 | 01076432111 | W | 1992-02-12 |
jiyoon22@hotmail.com | 김지윤 | 01032324117 | W | 1992-02-22 |
jihoon93@hanmail.net | 김지훈 | 01023258688 | M | 1993-02-23 |
seoyeons@naver.com | 박서연 | 01076482209 | W | 1993-03-16 |
yoonsy94@gmail.com | 윤서연 | NULL | W | 1994-03-19 |
MEMBER_ID | MEMBER_NAME | GENDER | DATE_OF_BIRTH |
---|---|---|---|
seoyeons@naver.com | 박서연 | W | 1993-03-16 |
DATE_OF_BIRTH
의 데이트 포맷이 예시와 동일해야 정답처리 됩니다.SELECT MEMBER_ID, MEMBER_NAME, GENDER, TO_CHAR(DATE_OF_BIRTH, 'YYYY-MM-DD') AS DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE GENDER = 'W'
and TO_CHAR(DATE_OF_BIRTH, 'MM') = '03'
and TLNO is not null
ORDER BY MEMBER_ID ;
FOOD_FACTORY
테이블입니다. FOOD_FACTORY
테이블은 다음과 같으며 FACTORY_ID
, FACTORY_NAME
, ADDRESS
, TLNO
는 각각 공장 ID, 공장 이름, 주소, 전화번호를 의미합니다.
Column name | Type | Nullable |
---|---|---|
FACTORY_ID | VARCHAR(10) | FALSE |
FACTORY_NAME | VARCHAR(50) | FALSE |
ADDRESS | VARCHAR(100) | FALSE |
TLNO | VARCHAR(20) | TRUE |
FOOD_FACTORY
테이블에서 강원도에 위치한 식품공장의 공장 ID, 공장 이름, 주소를 조회하는 SQL문을 작성해주세요. 이때 결과는 공장 ID를 기준으로 오름차순 정렬해주세요.SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
FROM FOOD_FACTORY
**WHERE ADDRESS LIKE '강원도%'**
ORDER BY FACTORY_ID
12세 이하인 여자 환자 목록 출력하기
darklight
sublimevimemacs
Oracle
다음은 종합병원에 등록된 환자정보를 담은 PATIENT
테이블입니다. PATIENT
테이블은 다음과 같으며 PT_NO
, PT_NAME
, GEND_CD
, AGE
, TLNO
는 각각 환자번호, 환자이름, 성별코드, 나이, 전화번호를 의미합니다.
Column name | Type | Nullable |
---|---|---|
PT_NO | VARCHAR(10) | FALSE |
PT_NAME | VARCHAR(20) | FALSE |
GEND_CD | VARCHAR(1) | FALSE |
AGE | INTEGER | FALSE |
TLNO | VARCHAR(50) | TRUE |
PATIENT
테이블에서 12세 이하인 여자환자의 환자이름, 환자번호, 성별코드, 나이, 전화번호를 조회하는 SQL문을 작성해주세요. 이때 전화번호가 없는 경우, 'NONE'으로 출력시켜 주시고 결과는 나이를 기준으로 내림차순 정렬하고, 나이 같다면 환자이름을 기준으로 오름차순 정렬해주세요.
-- 코드를 입력하세요
SELECT PT_NAME, PT_NO, GEND_CD, AGE, COALESCE(TLNO, 'NONE') AS TLNO
FROM PATIENT
WHERE GEND_CD = 'W'
AND AGE <= 12
ORDER BY AGE DESC, PT_NAME
FIRST_HALF
테이블과 아이스크림 성분에 대한 정보를 담은 ICECREAM_INFO
테이블입니다. FIRST_HALF
테이블 구조는 다음과 같으며, SHIPMENT_ID
, FLAVOR
, TOTAL_ORDER
는 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 상반기 아이스크림 총주문량을 나타냅니다. FIRST_HALF
테이블의 기본 키는 FLAVOR
입니다.
NAME | TYPE | NULLABLE |
---|---|---|
SHIPMENT_ID | INT(N) | FALSE |
FLAVOR | VARCHAR(N) | FALSE |
TOTAL_ORDER | INT(N) | FALSE |
ICECREAM_INFO
테이블 구조는 다음과 같으며, FLAVOR
, INGREDITENT_TYPE
은 각각 아이스크림 맛, 아이스크림의 성분 타입을 나타냅니다. INGREDIENT_TYPE
에는 아이스크림의 주 성분이 설탕이면 sugar_based
라고 입력되고, 아이스크림의 주 성분이 과일이면 fruit_based
라고 입력됩니다. ICECREAM_INFO
의 기본 키는 FLAVOR
입니다. ICECREAM_INFO
테이블의 FLAVOR
는 FIRST_HALF
테이블의 FLAVOR
의 외래 키입니다.
NAME | TYPE | NULLABLE |
---|---|---|
FLAVOR | VARCHAR(N) | FALSE |
INGREDIENT_TYPE | VARCHAR(N) | FALSE |
-- 코드를 입력하세요
SELECT f.FLAVOR
FROM FIRST_HALF f
LEFT JOIN ICECREAM_INFO i
ON f.FLAVOR = i.FLAVOR
WHERE f.TOTAL_ORDER > 3000
AND INGREDIENT_TYPE = 'fruit_based'
ORDER BY TOTAL_ORDER DESC
SELECT F.FLAVOR
FROM
(SELECT FLAVOR
FROM FIRST_HALF
WHERE TOTAL_ORDER > 3000
ORDER BY TOTAL_ORDER DESC ) F,
ICECREAM_INFO I
WHERE F.FLAVOR = I.FLAVOR
AND I.INGREDIENT_TYPE = 'fruit_based'
SELECT F.FLAVOR
FROM FIRST_HALF F, ICECREAM_INFO I
WHERE F.FLAVOR = I.FLAVOR
AND TOTAL_ORDER > 3000
AND INGREDIENT_TYPE = 'fruit_based'
ORDER BY F.FLAVOR
-- 코드를 입력하세요
SELECT DR_NAME, DR_ID, MCDP_CD, TO_CHAR(HIRE_YMD, 'YYYY-MM-DD')
FROM DOCTOR
WHERE MCDP_CD = 'CS'
OR MCDP_CD = 'GS'
ORDER BY HIRE_YMD DESC, DR_NAME
select dr_name, dr_id, mcdp_cd, to_char(hire_ymd, 'yyyy-mm-dd')
from doctor
where mcdp_cd ~~**is**~~ in ('CS', 'GS')
order by hire_ymd desc, dr_name
-- 코드를 입력하세요
SELECT count(user_id)
from user_info
where to_char(joined, 'yy') = '21'
and age between 20 and 29
select name
from animal_ins
where datetime = (select min(datetime)
from animal_ins)
select name
from animal_ins
**order by datetime
limit 1**
oracle using in-line view subquery select name
from (select name from animal_ins order by datetime)
where **rownum** = 1
-- 코드를 입력하세요
select animal_id, name, datetime
from animal_ins
order by name, datetime DESC
is not (x)
-- 코드를 입력하세요
SELECT animal_id, name
from animal_ins
where intake_condition != 'Aged'
order by animal_id
ONLINE_SALE
테이블 입니다. ONLINE_SALE
테이블은 아래와 같은 구조로 되어있으며 ONLINE_SALE_ID
, USER_ID
, PRODUCT_ID
, SALES_AMOUNT
, SALES_DATE
는 각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
Column name | Type | Nullable |
---|---|---|
ONLINE_SALE_ID | INTEGER | FALSE |
USER_ID | INTEGER | FALSE |
PRODUCT_ID | INTEGER | FALSE |
SALES_AMOUNT | INTEGER | FALSE |
SALES_DATE | DATE | FALSE |
ONLINE_SALE
테이블에서 동일한 회원이 동일한 상품을 재구매한 데이터를 구하여, 재구매한 회원 ID와 재구매한 상품 ID를 출력하는 SQL문을 작성해주세요. 결과는 회원 ID를 기준으로 오름차순 정렬해주시고 회원 ID가 같다면 상품 ID를 기준으로 내림차순 정렬해주세요.select user_id, product_id
from online_sale
group by user_id, product_id
having count(*) > 1
order by user_id, product_id desc
HAVING 문에서는 이전 포스팅에서 다룬 집계함수를 통해 조건을 추가할 수 있어요!select sales_date, product_id, **NULL AS user_id**, sales_amount
from offline_sale
union all 이 데이터처리에 있어서 빠름
💡 **[어떤 블로거의 의견](http://intomysql.blogspot.com/2011/01/union-union-all.html)**결론은,
UNION 이든지 UNION ALL이든지 사실 그리 좋은 SQL 작성은 아니다.
UNION이 필요하다는 것은 사실 두 엔터티(테이블)가 하나의 엔터티(테이블)로 통합이 되었어야
할 엔터티들이었는데, 알 수 없는 이유로 분리 운영되는 경우가 상당히 많다.
즉 모델링 차원에서 엔터티를 적절히 통합하여 UNION의 요건을 모두 제거하자.
두 집합에 절대 중복된 튜플(레코드)가 발생할 수 없다는 보장이 있다면 UNION ALL을 꼭 사용하자.
두 집합에서 모두 각각의 PK를 조회하는데, 그 두 집합의 PK가 절대 중복되지 않는 형태
중복이 있다 하더라도 그리 문제되지 않는다면 UNION 보다는 UNION ALL을 사용하자.
만약 UNION이나 UNION ALL을 사용해야 한다면, 최소 필요 컬럼만 SELECT 하자.
내 답: 전부 합친 테이블을 만들어서 거기서 조건을 추가함
-- 판매 날짜, 상품ID, 유저ID, 판매량
select to_char(sales_date, 'yyyy-mm-dd') as sales_date, product_id, user_id, sales_amount
from (select sales_date, product_id, user_id, sales_amount
from online_sale
union
select sales_date, product_id, NULL AS user_id, sales_amount
from offline_sale)
where to_char(sales_date, 'mm') = '03'
order by sales_date, product_id, user_id
다른사람들 해답
select date_format(sales_date, '%Y-%m-%d') as sales_date, product_id, user_id, sales_amount
from online_sale
where sales_date >= '2022-03-01' and sales_date < '2022-04-01'
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 >= '2022-03-01' and sales_date < '2022-04-01'
order by sales_date, product_id, user_id
조건을 적용한 각각의 테이블을 union all
23
→ 00023 lpad(대상, 범위, 넣을내용)
5
→ 5.00
to_char(대상, ‘FM9.00’)
FM99.00
select lpad(i.rest_id, 5, 0) as rest_id, i.rest_name, i.food_type, i.favorites, i.address, to_char(r.score, 'FM9.00') as score
from (select rest_id, round(avg(review_score), 2) as score
from rest_review
group by rest_id) r,
rest_info i
where i.rest_id = r.rest_id
and address like '서울%'
order by score desc, favorites desc
SELECT count(unique(name))
from animal_ins
distinct 사용
count(distinct name)
DISTINCT : 중복을 없애주지만 정렬을 해주지 않는다.
GROUP BY : 중복을 없애주고 정렬도 해준다.
이 때 GROUP BY는 그루핑 뿐만 아니라 정렬까지 수행하기 때문에 속도면에서 DISTINCT가 빠를 수 있다.상황에 맞게 적절히 사용하자.
SELECT *
FROM FOOD_PRODUCT
WHERE PRICE =
(SELECT MAX(PRICE) PRICE FROM FOOD_PRODUCT);
SELECT mcdp_cd 진료과코드, count(*) "5월예약건수"
from appointment
where to_char(apnt_ymd, 'yymm') = '2205'
group by mcdp_cd
**order by 2 , 1**
→ 정답은 같게 나오는데 왜 이게 오답 포인트인지..?
다른사람
SELECT "진료과코드", "5월예약건수"
FROM(SELECT MCDP_CD AS "진료과코드",
SUM(CASE WHEN TO_CHAR(APNT_YMD, 'MM') = '05' THEN 1 END) AS "5월예약건수"
FROM APPOINTMENT
GROUP BY MCDP_CD)
WHERE "5월예약건수" IS NOT NULL
ORDER BY "5월예약건수" ASC, "진료과코드" ASC
SELECT animal_type, count(*)
from animal_ins
group by animal_type
order by animal_type
-- 코드를 입력하세요
select *
from (SELECT name, count(name) count
from animal_ins
group by name)
where count > 1
order by name
points
select author_id, author_name, category, sum(total_sales)
from (select a.author_id, a.author_name, category, (price*sales) total_sales
from book b
join (select book_id, sum(sales) sales
from book_sales
where to_char(sales_date, 'yymm') = 2201
group by book_id) bs
on b.book_id = bs.book_id
join author a
on a.author_id = b.author_id)
group by author_id,author_name, category
order by author_id, category desc
select a.author_id, a.author_name, b.category, sum(bs.sales * b.price) as total_sales
from author a
inner join b on a.author_id = b.author_id
inner join book_sales bs on b.book_id = bs.book_id
where to_char(bs.sales_date, 'yymm') = '2201'
group by a.author_id, a.author_name, b.category
order by a.author_id, b.category desc
https://yongku.tistory.com/entry/프로그래머스SQL-저자-별-카테고리-별-매출액-집계하기-오라클Oracle
항상 세로 성분인지 가로 성분인지 정확하게 인지하는 것이 중요하다. 연산도 세로인지 가로인지 중요하다. 인지만 잘한다면 크게 어렵지 않은 문제이다.
판매정보에 각 고유정보를 JOIN 후, 날짜로 분기하여 GROUP BY 하여 SELECT 문에서 적절한 SUM() 연산을 하면 된다.
https://velog.io/@sheltonwon/SQL연습-저자-별-카테고리-별-매출액-집계하기-프로그래머스
select ingredient_type, sum(total_order) total_order
from first_half f, icecream_info i
**where f.flavor= i.flavor**
group by ingredient_type
order by total_order
내 답
select trunc(price, -4) price_group, count(*) products
from product
group by trunc(price, -4)
order by trunc(price, -4)
trunc, case when
select truncate(price, -4) as price_group, count(product_id) as products
from product
group by price_group
order by price_group
select trunc(price, -4) price_group, count(*) as products
from product
group by price_group
order by price_group
SELECT FLOOR(PRICE/10000)*10000 AS PRICE_GROUP
, COUNT(*) AS PRODUCTS
FROM product
GROUP
BY PRICE_GROUP
ORDER
BY PRICE_GROUP ASC
SELECT CASE WHEN (0 < PRICE) AND (PRICE < 10000) then 0
WHEN (10000 <= PRICE) and (PRICE < 20000) then 10000
WHEN (20000 <= PRICE) and (PRICE < 30000) then 20000
WHEN (30000 <= PRICE) and (PRICE < 40000) then 30000
WHEN (40000 <= PRICE) and (PRICE < 50000) then 40000
WHEN (50000 <= PRICE) and (PRICE < 60000) then 50000
WHEN (60000 <= PRICE) and (PRICE < 70000) then 60000
WHEN (70000 <= PRICE) and (PRICE < 80000) then 70000
WHEN (80000 <= PRICE) and (PRICE < 90000) then 80000
END AS PRICE_GROUP, count(*)
FROM PRODUCT
GROUP
BY PRICE_GROUP
ORDER
BY PRICE_GROUP ASC
LTRIM, RTRIM
datetime hh 12시간 , HH 24시간 HH24 HH12
to_number
SELECT to_number(to_char(datetime, 'HH24')) hour, count(*) count
from animal_outs
where to_number(to_char(datetime, 'HH24')) between 09 and 19
group by to_number(to_char(datetime, 'HH24'))
order by hour
select hour(datetime) as HOUR,
count(*) as COUNT
from animal_outs
where hour(datetime) between 9 and 19
group by HOUR
order by HOUR asc;
ORACLE, MYSQL 날짜에서 각 값들을 추출하기 🧐
WHERE options REGEXP '통풍시트|열선시트|가죽시트'
→ mysql로는 되는데 오라클은 안됨. WHERE OPTIONS LIKE '%시트%'
-- 코드를 입력하세요
SELECT car_type, count(car_type) cars
from car_rental_company_car
WHERE OPTIONS LIKE '%시트%'
group by car_type
order by car_type
select f.food_type, rest_id, rest_name, f.favorites
from (select food_type, max(favorites) favorites
from rest_info
group by food_type) f, rest_info r
where f.food_type = r.food_type
**and f.favorites = r.favorites**
order by food_type desc
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;
select food_type, rest_id,rest_name, favorites
from(
select food_type, rest_id,rest_name, favorites,
rank() over(partition by food_type order by favorites desc) as rk
from REST_INFO
)
where rk = 1
order by food_type desc
rank() partition byselect category, sum(sales) total_sales
from (SELECT book_id, category
from book) b,
book_sales s
where b.book_id = s.book_id
and to_char(sales_date, 'yymm') = '2201'
group by category
order by category asc;
-- -- 코드를 입력하세요
select to_number(to_char(start_date , 'mm')) month, car_id, count(car_id) records
from (select CAR_ID, START_DATE, count(car_id) over(partition by car_id) as records
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
**where to_char(start_date, 'yymm') in ('2208' , '2209', '2210')**) r
where r.records **>= 5**
group by to_char(start_date, 'mm'), car_id
order by to_char(start_date, 'mm'), car_id desc
SELECT MONTH, CAR_ID, RECORDS
FROM (
SELECT DISTINCT MONTH(START_DATE) AS MONTH
, CAR_ID
, COUNT(*) OVER(PARTITION BY MONTH(START_DATE), CAR_ID) AS RECORDS
, COUNT(*) OVER(PARTITION BY CAR_ID) AS FILTER
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE BETWEEN '2022-08-01' AND '2022-10-31'
)A
WHERE FILTER >= 5
ORDER BY MONTH ASC, CAR_ID DESC
select category, price, product_name
from (SELECT category, PRODUCT_NAME, PRICE, max(price) over (partition by category) maxprice
from food_product)
where price = maxprice
and category in ('과자', '국', '김치', '식용유')
order by price desc
select CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
from food_product
where (category, price) in ( SELECT category, max(price) as price
from FOOD_PRODUCT
where category in ('과자', '국', '김치', '식용유')
group by category)
order by price desc
1-10 연속된 숫자 조회
select level as no
from dual
connect by level <= 10
22년 1월부터 12월까지 출력
select '2022년'||lpad(level, 2, 0)||'월' as no
from dual
connect by level <= 12
특정 날짜 구간 조회
select hour, count(datetime) count
from (select level -1 as hour
from dual
connect by level <= 24) t2
**left join** animal_outs t1
on t2.hour = to_char(t1.datetime, 'HH24')
group by hour
order by hour asc
[Oracle] 프로그래머스 - 입양 시각 구하기 (2)select t2.lv hour, nvl(t1.cnt, 0) count
from (select to_char(datetime, 'HH24') hour, count(*) cnt
from animal_outs
group by to_char(datetime, 'HH24')
order by hour
) t1,
(select level -1 lv
from dual
connect by level <= 24) t2
where t2.lv = t1.hou**r(+)**
order by t2.lv
[PROGRAMMER Level-4] 입양 시각 구하기(2)[Oracle](+)는 outer join 연산자
❗️Oracle에서 OUTER JOIN 연산자는 (+) 입니다.
❗️조인시킬 값이 없는 조인 측에 (+)를 위치시킵니다.
❗️OUTER JOIN 연산자는 표현식의 한 편에만 올 수 있습니다.
❗️매칭되는 데이터가 없는 경우, NULL로 표시합니다.
💡 이유는 모르겠지만 연도와 월을 추출하는 과정에서 to_char을 사용하니까 오답으로 인식하는 것 같네요날짜 정보 추출 함수인 extract 함수를 사용하면 정답으로 인식합니다.extract 사용법은 아래와 같습니다.extract(year from sales_date) as YEAR,extract(month from sales_date) sa MONTH
group by 절도 extract 함수로 바꿔주세요.group by extract(year from SALES_DATE),extract(month from SALES_DATE), GENDER
자세한 함수 사용법은 아래 블로그를 참고하세요.https://blog.naver.com/PostView.nhn?blogId=regenesis90&logNo=222226229952
-- 코드를 입력하세요
SELECT to_char(sales_date, 'YYYY') year, to_char(sales_date, 'MM') month, u.gender, count(**distinct u.user_id**) users
from online_sale s, user_info u
where s.user_id = u.user_id
and u.gender is not null
group by to_char(sales_date, 'YYYY'), to_char(sales_date, 'MM'), u.gender
order by year, month, gender
distinct : 같은 회원이 여러 번 구매하는 경우가 있기 때문에 중복 제거를 위해 사용 … 요구사항이 연, 월 성별 구매회원이었음,, 1월에 여러번 사도 한번으로 count해야 2023.01.01 이랑 2023.01.05 는 년/월 은 같은데 날짜는 달라요nvl
-- 코드를 입력하세요
SELECT warehouse_id, warehouse_name, address, nvl(freezer_yn, 'N') freezer_yn
from food_warehouse
where address like '경기%'
order by warehouse_id
SELECT animal_id
from animal_ins
where name is null
order by animal_id
-- 코드를 입력하세요
SELECT animal_id
from animal_ins
where name is not null
order by animal_id
SELECT count(*) users
from user_info
where age is null
-- 코드를 입력하세요
SELECT animal_type, nvl(name, 'No name'), sex_upon_intake
from animal_ins
order by animal_id
ANIMAL_INS
테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS
테이블 구조는 다음과 같으며, ANIMAL_ID
, ANIMAL_TYPE
, DATETIME
, INTAKE_CONDITION
, NAME
, SEX_UPON_INTAKE
는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.
NAME | TYPE | NULLABLE |
---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
INTAKE_CONDITION | VARCHAR(N) | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_INTAKE | VARCHAR(N) | FALSE |
ANIMAL_OUTS
테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS
테이블 구조는 다음과 같으며, ANIMAL_ID
, ANIMAL_TYPE
, DATETIME
, NAME
, SEX_UPON_OUTCOME
는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS
테이블의 ANIMAL_ID
는 ANIMAL_INS
의 ANIMAL_ID
의 외래 키입니다.
NAME | TYPE | NULLABLE |
---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
ANIMAL_INS
테이블과 ANIMAL_OUTS
테이블이 다음과 같다면 ANIMAL_INS
ANIMAL_ID | ANIMAL_TYPE | DATETIME | INTAKE_CONDITION | NAME | SEX_UPON_INTAKE |
---|---|---|---|---|---|
A352713 | Cat | 2017-04-13 16:29:00 | Normal | Gia | Spayed Female |
A350375 | Cat | 2017-03-06 15:01:00 | Normal | Meo | Neutered Male |
ANIMAL_OUTS
ANIMAL_ID | ANIMAL_TYPE | DATETIME | NAME | SEX_UPON_OUTCOME |
---|---|---|---|---|
A349733 | Dog | 2017-09-27 19:09:00 | Allie | Spayed Female |
A352713 | Cat | 2017-04-25 12:25:00 | Gia | Spayed Female |
A349990 | Cat | 2018-02-02 14:18:00 | Spice | Spayed Female |
ANIMAL_OUTS
테이블에서Allie의 ID는 ANIMAL_INS
에 없으므로, Allie의 데이터는 유실되었습니다.
Gia의 ID는 ANIMAL_INS
에 있으므로, Gia의 데이터는 유실되지 않았습니다.
Spice의 ID는 ANIMAL_INS
에 없으므로, Spice의 데이터는 유실되었습니다.
따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.
ANIMAL_ID | NAME |
---|---|
A349733 | Allie |
A349990 | Spice |
-- 코드를 입력하세요
SELECT o.animal_id, o.name
from animal_ins i, animal_outs o
where o.animal_id = i.animal_id(+)
and sex_upon_intake is null
order by o.animal_id
서브쿼리 이용
select animal_id,name
from animal_outs
where animal_id not in (select animal_id from animal_ins)
order by 1
ANIMAL_INS
테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS
테이블 구조는 다음과 같으며, ANIMAL_ID
, ANIMAL_TYPE
, DATETIME
, INTAKE_CONDITION
, NAME
, SEX_UPON_INTAKE
는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.
NAME | TYPE | NULLABLE |
---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
INTAKE_CONDITION | VARCHAR(N) | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_INTAKE | VARCHAR(N) | FALSE |
ANIMAL_OUTS
테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS
테이블 구조는 다음과 같으며, ANIMAL_ID
, ANIMAL_TYPE
, DATETIME
, NAME
, SEX_UPON_OUTCOME
는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS
테이블의 ANIMAL_ID
는 ANIMAL_INS
의 ANIMAL_ID
의 외래 키입니다.
NAME | TYPE | NULLABLE |
---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
ANIMAL_INS
테이블과 ANIMAL_OUTS
테이블이 다음과 같다면 ANIMAL_INS
ANIMAL_ID | ANIMAL_TYPE | DATETIME | INTAKE_CONDITION | NAME | SEX_UPON_INTAKE |
---|---|---|---|---|---|
A350276 | Cat | 2017-08-13 13:50:00 | Normal | Jewel | Spayed Female |
A381217 | Dog | 2017-07-08 09:41:00 | Sick | Cherokee | Neutered Male |
ANIMAL_OUTS
ANIMAL_ID | ANIMAL_TYPE | DATETIME | NAME | SEX_UPON_OUTCOME |
---|---|---|---|---|
A350276 | Cat | 2018-01-28 17:51:00 | Jewel | Spayed Female |
A381217 | Dog | 2017-06-09 18:51:00 | Cherokee | Neutered Male |
ANIMAL_ID | NAME |
---|---|
A381217 | Cherokee |
-- 코드를 입력하세요
SELECT i.animal_id, i.name
from animal_ins i, animal_outs o
where i.animal_id = o.animal_id
and i.datetime > o.datetime
order by i.datetime
ANIMAL_INS
테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS
테이블 구조는 다음과 같으며, ANIMAL_ID
, ANIMAL_TYPE
, DATETIME
, INTAKE_CONDITION
, NAME
, SEX_UPON_INTAKE
는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.
NAME | TYPE | NULLABLE |
---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
INTAKE_CONDITION | VARCHAR(N) | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_INTAKE | VARCHAR(N) | FALSE |
ANIMAL_OUTS
테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS
테이블 구조는 다음과 같으며, ANIMAL_ID
, ANIMAL_TYPE
, DATETIME
, NAME
, SEX_UPON_OUTCOME
는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS
테이블의 ANIMAL_ID
는 ANIMAL_INS
의 ANIMAL_ID
의 외래 키입니다.
NAME | TYPE | NULLABLE |
---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
ANIMAL_INS
테이블과 ANIMAL_OUTS
테이블이 다음과 같다면 ANIMAL_INS
ANIMAL_ID | ANIMAL_TYPE | DATETIME | INTAKE_CONDITION | NAME | SEX_UPON_INTAKE |
---|---|---|---|---|---|
A354597 | Cat | 2014-05-02 12:16:00 | Normal | Ariel | Spayed Female |
A373687 | Dog | 2014-03-20 12:31:00 | Normal | Rosie | Spayed Female |
A412697 | Dog | 2016-01-03 16:25:00 | Normal | Jackie | Neutered Male |
A413789 | Dog | 2016-04-19 13:28:00 | Normal | Benji | Spayed Female |
A414198 | Dog | 2015-01-29 15:01:00 | Normal | Shelly | Spayed Female |
A368930 | Dog | 2014-06-08 13:20:00 | Normal | Spayed Female |
ANIMAL_OUTS
ANIMAL_ID | ANIMAL_TYPE | DATETIME | NAME | SEX_UPON_OUTCOME |
---|---|---|---|---|
A354597 | Cat | 2014-05-02 12:16:00 | Ariel | Spayed Female |
A373687 | Dog | 2014-03-20 12:31:00 | Rosie | Spayed Female |
A368930 | Dog | 2014-06-13 15:52:00 | Spayed Female |
NAME | DATETIME |
---|---|
Shelly | 2015-01-29 15:01:00 |
Jackie | 2016-01-03 16:25:00 |
Benji | 2016-04-19 13:28:00 |
outer join
select *
from (select i.name, i.datetime
from animal_ins i, animal_outs o
where i.animal_id = o.animal_id (+)
and o.datetime is null
order by datetime
)
where rownum < 4
subquery
select name, datetime
from (select *
from animal_ins
where animal_id not in (select animal_id
from animal_outs)
order by datetime)
where rownum < 4
LIMIT 3
, FETCH FIRST 3 ROW ONLY
활용하기!PRODUCT
테이블과 오프라인 상품 판매 정보를 담은 OFFLINE_SALE
테이블 입니다. PRODUCT
테이블은 아래와 같은 구조로 PRODUCT_ID
, PRODUCT_CODE
, PRICE
는 각각 상품 ID, 상품코드, 판매가를 나타냅니다.
Column name | Type | Nullable |
---|---|---|
PRODUCT_ID | INTEGER | FALSE |
PRODUCT_CODE | VARCHAR(8) | FALSE |
PRICE | INTEGER | FALSE |
OFFLINE_SALE
테이블은 아래와 같은 구조로 되어있으며 OFFLINE_SALE_ID
, PRODUCT_ID
, SALES_AMOUNT
, SALES_DATE
는 각각 오프라인 상품 판매 ID, 상품 ID, 판매량, 판매일을 나타냅니다.
Column name | Type | Nullable |
---|---|---|
OFFLINE_SALE_ID | INTEGER | FALSE |
PRODUCT_ID | INTEGER | FALSE |
SALES_AMOUNT | INTEGER | FALSE |
SALES_DATE | DATE | FALSE |
PRODUCT
테이블과 OFFLINE_SALE
테이블에서 상품코드 별 매출액(판매가 * 판매량) 합계를 출력하는 SQL문을 작성해주세요. 결과는 매출액을 기준으로 내림차순 정렬해주시고 매출액이 같다면 상품코드를 기준으로 오름차순 정렬해주세요.PRODUCT
테이블이 다음과 같고
PRODUCT_ID | PRODUCT_CODE | PRICE |
---|---|---|
1 | A1000011 | 15000 |
2 | A1000045 | 8000 |
3 | C3000002 | 42000 |
OFFLINE_SALE
테이블이 다음과 같다면
OFFLINE_SALE_ID | PRODUCT_ID | SALES_AMOUNT | SALES_DATE |
---|---|---|---|
1 | 1 | 2 | 2022-02-21 |
2 | 1 | 2 | 2022-03-02 |
3 | 3 | 3 | 2022-05-01 |
4 | 2 | 1 | 2022-05-24 |
5 | 1 | 2 | 2022-07-14 |
6 | 2 | 1 | 2022-09-22 |
PRODUCT_CODE
가 A1000011
인 상품은 총 판매량이 6개, 판매가가 15,000원
PRODUCT_CODE
가 A1000045
인 상품은 총 판매량이 2개, 판매가가 8,000원
PRODUCT_CODE
가 C3000002
인 상품은 총 판매량이 3개, 판매가가 42,000원
그러므로 각 상품 별 매출액을 계산하고 정렬하면 결과가 다음과 같이 나와야 합니다.
PRODUCT_CODE | SALES |
---|---|
C3000002 | 126000 |
A1000011 | 90000 |
A1000045 | 16000 |
select product_code, (price*amount)sales
from (select product_id, sum(sales_amount) amount
from offline_sale
group by product_id) s, product p
where p.product_id = s.product_id
order by sales desc, product_code
select p.product_code, (p.price * o.sales_amount) sales
from offline_sale o, product p
where i.product_id = p.product_id
group by p.produdct_code
order by sales desc, b.product_code