오랜만에 SQL 문제를 풀어보자

당장은 html 이나 javascript 쪽이 중요하지만

그래도 까먹지 않을 정도로만 SQL도 학습하려 한다.

 

 

성분으로 구분한 아이스크림 총 주문량

 

늘 하던대로, 테이블을 합치고 정렬을 하면 될듯하다.

 

딱히 함정은 없는듯해 보임

 

select  i.ingredient_type, sum(f.total_order) as TOTAL_ORDER
from first_half f left join icecream_info i on f.flavor = i.flavor
group by i.ingredient_type
order by f.total_order

 

역시, 간단한 문제였다

 

 

 

 

루시와 엘라 찾기

 

마찬가지로 간단한 문제인데,

여러 이름을 찾아야 하기 때문에 

where name like 를 여러번 적는것 보다 

 

where name in  을 써주면 간단하다.

select animal_id, name, sex_upon_intake
from animal_ins
where name in ('Lucy','Ella','Pickle','Rogan','Sabrina','Mitty')
order by 1

 

 

'사전캠프' 카테고리의 다른 글

27일차 - 알고리즘 풀이  (0) 2024.07.29
26일차 - 알고리즘 풀이  (0) 2024.07.25
25일차 - 알고리즘 풀이  (3) 2024.07.24
24일차 - 알고리즘 풀이  (1) 2024.07.23
23일차 - 알고리즘 풀이  (3) 2024.07.22

오늘도 SQL 학습이다.

아무래도 java와 매일 왔다갔다 하면서 배우기 보다는

주 간격으로 따로 학습하는것이 조금 덜 헷갈리지 않을까 싶다.

 

 

액셀보다 쉽고 빠른 SQL

엑셀보다 쉽다는 생각이 잘 들지 않음

 

 

 

이것은 바로 어제 SQL 문제풀이에서 봤던 내용이다.

본의 아니게 예습을 해버림

 

어제 놓쳤던 부분이 있는데, date_format 함수를 사용하려면

해당 컬럼이 날짜 형식의 데이터 서식으로 되어 있어야 한다.

 

DBeaver 에서는 시계모양으로 데이터의 서식을 알 수 있으며, 

만약 문자열(ABC) 서식일 경우 

 

date(칼럼명) 으로 날짜형식의 서식으로 변경할 수 있다.

당연하지만 이 때, 칼럼내 데이터가 날짜에 관련된 내용이어야 한다.

select date(date) date_type,
       date_format(date(date), '%Y') "년",
       date_format(date(date), '%m') "월",
       date_format(date(date), '%d') "일",
       date_format(date(date), '%w') "요일"
from payments

date() 와  date_format 함수를 적용한 모습

 

 

어제 학습한 내용처럼, 다른 내용들 또한 표시 할 수 있다.

 

 

어떤 데이터든 간에, 데이터가 기록된 시간은 굉장히 중요하고 항상 필요로 하기 때문에

date_format 은 꼭 알아둬야 할 것 같다.

 

 

 

어김없이 돌아온 숙제 시간

 

아쉽게도 date 에 해당하는 내용은 아니다.

 

우선, 음식 타입별, 연령별 주문건수 를 구하고 서브쿼리를 활용해

pivot view 를 구성하면 될 것 같다.

(사실 처음 봤을땐 역시나 뇌가 정지했지만, 어제 미리 해봤기 때문에 오늘은 다르다 !)

 

우선, 음식 타입의 내용은 food_orders  table에 있고

age 내용은 customers  table 에 있기 때문에 

SELECT * 
from food_orders fo inner join customers c on fo.customer_id = c.customer_id

두 table을 join 해준다

customers 의 내용이 null이라면 카운트할 이유가 없기 때문에 inner join을 써줌

 

10~59세만 해당하기 때문에 where 에서 걸러주고, 

나이대를 case when  으로 나눠준다

 

SELECT cuisine_type,
		case when age between 10 and 19 then '10'
		     when age between 20 and 29 then '20'
		     when age between 30 and 39 then '30'
		     when age between 40 and 49 then '40'
		     when age between 50 and 59 then '50'		
		end sage
from food_orders fo inner join customers c on fo.customer_id = c.customer_id 
where age >= 10 and age <= 59

 

when ~ 복붙을 할 때는 언제나 꼼꼼히 수정해야함

(case 도 같이 복사하면 즉시 에러)

그 다음  group by 1,2 로 음식별, 나이대별로 그룹정렬을 해준 뒤

count(1) 을 추가해서 음식점별, 나이대 별 주문 수량을 count 

 

이후 서브쿼리로 넘어가서 pivot view를 구성해주면 마무리인데

 

이 부분에서 에러가 계속 나와서 엄청 헤맸다  

메인쿼리 끝에 명칭지정을 안해주면 에러가 나는것임.. 왜 그런지는 모르겠지만

 

(메인쿼리 ) a   이 a가 꼭 필요

SELECT cuisine_type,
		max(if(sage='10', count_order, 0)) "10대",
		max(if(sage='20', count_order, 0)) "20대",
		max(if(sage='30', count_order, 0)) "30대",
		max(if(sage='40', count_order, 0)) "40대",
		max(if(sage='50', count_order, 0)) "50대"		
from
(
SELECT cuisine_type,
		case when age between 10 and 19 then '10'
		     when age between 20 and 29 then '20'
		     when age between 30 and 39 then '30'
		     when age between 40 and 49 then '40'
		     when age between 50 and 59 then '50'		
		end sage,
		count(1) count_order
from food_orders fo inner join customers c on fo.customer_id = c.customer_id
where age >= 10 and age <= 59
group by 1, 2
) a
group by 1

 

복붙신공 max  if절로 pivot view 를 구성한다.

그다음 음식별로 묶기 위해 다시 group by 1 을 해주면 완성

order by 에 대한 내용은 없기 때문에 여기서 마무리 !!

 

잘 잘동한다. 예습하길 잘했다 !

 

 

엑셀보다 쉽고 빠른 SQL

사전캠프 강의 부분은 이것으로 마무리가 되었다.

기초적인 부분이었으나 아직 활용 부분에서 많이 서투르고 기억이 나지 않을 때가 있다.

그래도, 이해가 안되는 부분은 없기 때문에 다행인것같다.

 

강의 속 튜터님은

완전히 이해하고 외우는것보다 조금씩 익숙해는것이 중요하다고 하셨지만,

 

아무래도 기초에 해당하는 내용은 어느정도 완벽에 가까워야 하지 않을까?

 

남은 사전캠프 기간동안 다른 유튜브 영상이나 SQL 문제풀이 를 통해

SQL 의 기초적인 부분을 계속 학습해야 할 것 같다.

 

'사전캠프' 카테고리의 다른 글

16일차 - Javascript 입문 수업  (0) 2024.07.11
15일차 - Javascript 입문 수업  (0) 2024.07.10
13일차 - 알고리즘 풀이  (0) 2024.07.08
12일차 - 액셀보다 쉽고 빠른 SQL  (0) 2024.07.04
11일차 - 알고리즘 풀이  (1) 2024.07.03

주말간 이사 때문에 정신이 없었다.

정신을 가다듬기 위해 알고리즘 문제를 푸는게 좋은것 같다.

 

오늘은 SQL 문제

 

 

뭔가 쉬워보이는듯한 문제이다.

 

SELECT animal_id,
	name,
	substr(datetime,1,10)
from animal_ins
order by 1

 

간단한 문제 !

 

라고 생각했지만,  문제의 제목이 눈에 띈다

 

딱 봐도 substr 말고 다른 함수를 쓰라고 하는듯한 눈빛이 느껴짐

 

 

물론 substr 을 써도 눈에 보이는 결과는 같아서 정답으로 처리되지만

소위 '가라' 에 가까운 방법이기 때문에,

 

 

정석의 방법을 찾아보기로 했다.

 

 

 

 

 

date_format 이라고 하는 날짜 포맷을 사용하여 원하는 표시형식으로 변경할 수 있다고 한다

 

date_format() 에 순서에 맞춰 (바꿀대상, 순서에 맞게 포맷문자, 문자열도 입력 가능 )

무려 '대소문자' 를 구분하기 때문에 주의

 

0000년-00월-00일 을 표기하고 싶다면

select date_format(datetime, '%Y년-%m월-%d일')  

라로 적어주면 된다. 

 

그럼 다시 위의 문제를 풀어보자.

select animal_id,
        name, 
        date_format(datetime, '%Y-%m-%d')
from animal_ins
order by 1

 

완성 !  

 

 

 

한 가지 문제를 더 풀어보자.

 

 

 

++ 주의사항으로 날짜 컬럼은 아래 예시와 같은 이름이어야한다.

 

천천히 배운걸 써보자

SELECT dr_name, dr_id, mcdp_cd, date_format(hire_ymd, '%Y-%m-%d') as 'HIRE_YMD'
from doctor
where mcdp_cd = 'CS' or mcdp_cd = 'GS' 
order by 4 desc, 1

 

바로 앞에서 배운 date_format 만 사용하면 된다 

딱히 어려운 점은 없었다.

 

 

하나만... 더 풀어볼까

 

이 내용은 강의에서 본 적이 있다.

order by , limit 를 사용하는 방법과

 

RANK 를 사용하는 법

뒤에껀 기억이 잘 나지 않음

 

select *
from food_product
order by price desc limit 1

이렇게 하면 price 의 내림차순으로, 1개 까지만 표시해준다.

 

 

 

다시 기억이 잘 나지 않는 RANK 를 학습해보자

 

 

RANK ()  over(order by 칼럼명 asc/desc) 

 

 

아앗.. 이제보니 rank 는 순서 정렬 보다는 등수를 매기는데 쓰는 함수였다.

다시 학습했으니 다음부턴 헷갈리지 말자 !

 

 

 

 

오늘은 다시 SQL을 학습하기로 했다.

 

시작은 간단한 복습 부터 !

마침 저번 강의 내용이 희미해져 가고있었다.

 

    1. 문자변경과 조건문
    👉 문자 변경
    1. REPLACE : 지정한 문자를 다른 문자로 변경
    2. SUBSTRING : 특정 문자만 추출
    3. CONCAT : 여러 문자를 합하여 포맷팅
    👉 조건문
    1. IF : if(조건, 조건을 충족할 때, 조건을 충족하지 못할 때)
    2. CASE WHEN END : case when 조건1 then 값(수식)1
                                                when 조건2 then 값(수식)2
                                                else 값(수식)3 end

 

오늘 학습 내용

  • Subquery 를 활용하여 복잡한 연산을 수행한다
  • Join 을 활용하여 여러개의 테이블에 있는 데이터를 한 번에 조회하고 연산한다

Subquery 는 한 번에 하기 힘든 여러 연산을 차근 차근 풀어서 쓸 때 사용한다고 이해했다.

컬럼의 평균값(AVG) 을 구한다음에 조건에 따라 해당 평균값에 추가로 연산해야 하는 경우 라던지, 

조건 자체를 연산의 결과로 하고 싶을 때 사용한다.

select restaurant_name,
       case when sum_of_quantity<=5 then 0.1
            when sum_of_quantity>15 and sum_of_price>=300000 then 0.005
            else 0.01 end ratio_of_add
from 
(
select restaurant_name,
       sum(quantity) sum_of_quantity,
       sum(price) sum_of_price
from food_orders
group by 1
) a

 

이 경우는,

restaurant_name 별로 quantity의 합, price의 합계를 먼저 구한다음

Subquery를 활용하여 추가로 합계된 값을 조건에 따라 case 로 나눠 표시해주도록 한 내용이다.

 

꽤 복잡하고 실습 과정에서 생각을 정리하는 시간이 길어졌다.

이해는 됐지만 정리가 제대로 안되었기 때문인데,

우선도를 파악하는 것이 중요했다.

 

제시된 문제에 따라 가장 먼저 mainquery에 기재할 내용과 이후 subquery 를 통해 마무리할 최종결과값을 나누어 생각해야한다.

그렇기 때문에, subquery를 잘 활용하기 위해선 문법보다는 우선 문제 자체를 해석하는 능력이 중요하다.

식당별 평균 음식 주문 금액과 주문자의 평균 연령을 기반으로 Segmentation 하기
- 평균 음식 주문 금액 기준 : 5,000 / 10,000 / 30,000 / 30,000 초과
- 평균 연령 : ~ 20대 / 30대 / 40대 / 50대 이상

 

위 문제를 보고 나는 10분 가량은 아무것도 할 수 없었다. 

문제 자체를 이해를 못했기 때문이다...

(문제가 다소 불친절한 감도 있지만)

 

어디서 부터 시작해야 하지? 

식당별 이니까, restaurant_name 을 group by 해야하고,

평균 음식 주문 금액은 avg(price), 평균 연령은 avg(age) 로 구해놓고 subquery 로 넘어간다.

subquery 에서 나머지 조건에 해당하는 부분을 case when 구문으로 나누어 표시되도록 하면 끝 !

SELECT restaurant_name,
	   avg_price,
	   avg_age,
		case when avg_price <= 5000  then 'price_group1' 
	        when avg_price  >  5000 and avg_price <= 10000 then 'price_group2'
	        when avg_price  > 10000 and avg_price <= 30000 then 'price group3'
	        when avg_price  > 30000 then 'price group4' end 'price group',
	    case when avg_age < 30 then 'age_group1'
	         when avg_age >= 30 and avg_age < 40 then 'age_group2'
	         when avg_age >= 40 and avg_age < 50 then 'age_group3'
	         else 'age_group4' end 'age group'
FROM
(
SELECT f.restaurant_name ,
	   f.price,
	   c.age,
	   AVG(f.price) avg_price ,
	   avg(c.age) avg_age
from food_orders f inner join customers c on f.customer_id =c.customer_id
group by 1
order by 1
) T

위와 같이 풀이 해 보았다. 잘 작동하는 듯 하다.



추가로, 
Join  에 대해서도 학습했는데, 

한 테이블 내에서가 아닌, 여러 테이블에서 데이터를 가져와야 하는 경우 사용한다.

 

따라서 테이블을 불러오는 From 뒤에 사용되며, 

from food_orders a left join customers b on a.customer_id=b.customer_id

위와 같이 From 메인 테이블 left join 불러올 테이블 on 메인 테이블.기준컬럼 = 불러울테이블.기준컬럼 

이라고 할 수 있다.

기억해야할 점은 두 테이블에 공통된 데이터가 있어야 한다는 것이다.

당연히, 기준도 없이 아무 테이블이나 마구잡이로 합칠 수 없다는 것

추가로
Left join의 경우 테이블에 빈 데이터가 있는 경우에 공백으로 불러오며

Inner join의 경우 두 테이블 모두 데이터가 있는 경우만 조회한다.

 

어제에 이어서 SQL 강의를 계속해서 들었다.

 

SQL 내에서 사용되는 명령어들을 '함수' 라고 부른다는것을 배우고

어제 배웠던 내용을 상기해보면,

Select *
From table
where 조건
		between A and B  사이  
        in (A, B, C)     하나라도 포함
       	like '%A%'		 A가 있는 
        
      필터링
        A and B          A B 전부 만족
        A or  B          A 이거나 B 일 때
        not A            A 가 아닐 때

간단한 내용들이었고

 

 

오늘 배운 내용은

	sum(컬럼)   전부 더하기
	avg(컬럼)   데이터 평균값
    count(컬럼)    데이터의 갯수 
    
	group by (컬럼)  컬럼내 데이터 종류별로 나열
    Order by (컬럼)  오름차순으로 컬럼 데이터 정렬  
    				 desc 내림차순

 

해당 칼럼 내의 데이터를 방법에 따라 계산한 결과를 표시하거나,

데이터의 표시 방법 등에 관한것을 배웠다.

 

조금 복잡하긴 했지만 이해하기에 어려운 수준은 아니었다.

 

추가로,

 replace(컬럼, 현재 값, 바꿀 값)
 		 컬럼 내의 현재 값과 일치하는 데이터를 바꿀 값으로 변경
        
 substring(컬럼, 시작점, 읽을 수)
 		   컬럼 내 데이터의 일부만 표기

 concat(값1, 값2, 값3)
 		임의의 값을 하나로 붙여서 표기

슬슬 어렵다는 느낌이 들었지만 여기까진 괜찮다.

 

IF(조건, 조건충족시, 불충족)

Case when 조건1 then 값(수식)1
     when 조건2 then 값(수식)2
     else 값(수식)3
     end

조건 지정의 대명사인 if 와 case를 배우면서 두뇌 회전이 지연되는듯 한 현상을 겪었다.

보는것만으로 이해되던것들이 잘 되지 않기 시작했다.

 

그래도 강의 영상을 멈춰두고 잠시 생각하는 것으로 이해하려고 노력했고 

시간이 좀 걸려도 이해하는데 무리는 없었다.

 

단순히 함수의 용도에 대한 이해도 중요하지만,

실질적인 활용 방법에 대해 생각할 수 있는 지능(?) 이 약간 별개라고 느껴진다.

 

이해했다고 생각한 부분도, 직접 써보려고 하니 버벅거리며 잘 되지 않았다.

 

 

머리속에서 날아가지 않게 주기적으로 직접 사용하는 복습이 중요 할 것 같다.

 

더보기
문제
다음의 조건으로 배달시간이 늦었는지 판단하는 값을 만들어주세요.
 

1. 다음의 조건으로 배달시간이 늦었는지 판단하는 값을 만들어주세요.

  • 주중 : 25분 이상
  • 주말 : 30분 이상

오늘 강의에서 제공한 문제를 풀어 보았는데, 

	   case when delivery_time >= if (day_of_the_week = 'weekend',30, 25) then 'Late'  
	   else 'On-time' end  "지연여부"

와 같은 case, if 구문을 이용해서 풀이 해 보았다.

late 표기 조건으로 주말은 30 이상, 그 외는 25 이상 인 경우, Late

나머지의 경우 On-time 으로 표기 하도록 해 보았다.

 

위 문제의 경우 주말과 주말 이외의 경우 밖에 없기 때문에 저런 식으로 사용 할 수 있었다.

사전캠프 2주차가 되었다.

 

등록이 조금 늦어졌기 때문에 오늘부터 강의를 지급받아 학습할 수 있었다.

첫 주차에는 강의가 없다보니 붕 뜬 것 같은 기분이었는데, 오늘부터는 본격적인 학습 진행이 가능할 듯 하다.

 

오늘 배운것은 SQL 기초 부분이다.

 

학습 이전에는 SQL  이 뭔지 아예 모르는 상태였다.

데이터 베이스 관리에 주로 쓰이는 언어.. 정도의 지식 뿐이었다.

(꽤나 정확했을지도)

 

다른 강의영상들과 마찬가지로, SQL 이 무엇인지,

  1. SQL 이란 무엇일까요?
      ❓ SQL 이 무엇이고 왜 필요한가요?
  • SQL 은 데이터베이스와 대화를 하기 위한 언어입니다.
  • 옆의 사람에게 필요한 것을 요청할 때 ‘A 를 주시겠어요?’ 와 하는 것과 같이 데이터베이스에게도 ‘A를 주겠니?’ 라고 이야기할 때 사용하는 언어라고 할 수 있습니다.

   

그리고  코딩에 대한 두려움을 줄여주는 응원문구 와 같은 것으로 시작했다.

 

 

본격적으로 강의에 들어가서,

 

DBeaver 를 설치하고, 강의에서 제공하는 Database Server에 연결한 뒤에 

해당 Database 내의 필요한 항목만을 불러오는 명령에 대한 내용을 배웠다.

  • select 
     - 테이블의 어떤 항목을 표시할지 (주로 열 로 구분된) 작성하는 부분
     - *  을 사용한다면 테이블 내의 항목을 전부 표시
  • from
     - 데이터를 가져올 테이블을 지정

이 두 가지가 SQL 에 아주 가장 대단히 기초적인 구문이라고 할 수 있다.

 

여기에 where 을 사용하여 테이블의 데이터 중 원하는 것만 가져올 수 있는데,

 

통상적으로 사용하는 것에는

where 테이블 between A and B  ---  A 와 B 사이의 값

                      in ( A, B, C)  --- A B C 하나라도 포함하는것

                      like '%A'   ---  A로 끝나는 값

 

 

추가로 조건을 추가하여 (논리연산)

필터링 조건을 더 할 수 있는데,

 

and  그리고    --- 모든 조건을 만족해야함 

or    또는        --- 하나라도 만족해야함

not   아닌       ---  해당값을 제외한

세 가지로 조건을 추가 할 수 있다.

 

예를 들어,

데이터 베이스 내의 음식목록(food)에서 가격(price)이 15000원 이상이면서 한국(cuisine)음식인 경우를 불러오고 싶다면

select *
from food
where price >= 15000 and cuisine = 'korean'

위 와 같이 사용할 수 있다.

 

사실 상 거의 따라했을 뿐인데 잘 작동하니 신기했다.

 

 

 

 

 

+ Recent posts