링크: https://school.programmers.co.kr/learn/courses/30/lessons/132204

 

 

습득한 점:

예시로 주어진 테이블을 반드시 보면서,

문제에서 주어진 말들을 오해하지 않고 빠르게 풀어야 겠다.

 

쉬워보인다고 해서 보지 않으면, 이렇게 쉬운 문제임에도 오히려 시간을 소모 할수 있다.

 

다음은 환자 정보를 담은 PATIENT 테이블과 의사 정보를 담은 DOCTOR 테이블, 그리고 진료 예약목록을 담은 APPOINTMENT에 대한 테이블입니다. PATIENT 테이블은 다음과 같으며 PT_NO, PT_NAME, GEND_CD, AGE, TLNO는 각각 환자번호, 환자이름, 성별코드, 나이, 전화번호를 의미합니다.

PT_NO VARCHAR(N) FALSE
PT_NAME VARCHAR(N) FALSE
GEND_CD VARCHAR(N) FALSE
AGE INTEGER FALSE
TLNO VARCHAR(N) TRUE

Column name Type Nullable

DOCTOR 테이블은 다음과 같으며 DR_NAME, DR_ID, LCNS_NO, HIRE_YMD, MCDP_CD, TLNO는 각각 의사이름, 의사ID, 면허번호, 고용일자, 진료과코드, 전화번호를 나타냅니다.

DR_NAME VARCHAR(N) FALSE
DR_ID VARCHAR(N) FALSE
LCNS_NO VARCHAR(N) FALSE
HIRE_YMD DATE FALSE
MCDP_CD VARCHAR(N) TRUE
TLNO VARCHAR(N) TRUE

Column name Type Nullable

APPOINTMENT 테이블은 다음과 같으며 APNT_YMD, APNT_NO, PT_NO, MCDP_CD, MDDR_ID, APNT_CNCL_YN, APNT_CNCL_YMD는 각각 진료 예약일시, 진료예약번호, 환자번호, 진료과코드, 의사ID, 예약취소여부, 예약취소날짜를 나타냅니다.

APNT_YMD TIMESTAMP FALSE
APNT_NO INTEGER FALSE
PT_NO VARCHAR(N) FALSE
MCDP_CD VARCHAR(N) FALSE
MDDR_ID VARCHAR(N) FALSE
APNT_CNCL_YN VARCHAR(N) TRUE
APNT_CNCL_YMD DATE TRUE

 

 

 

문제:

PATIENT, DOCTOR 그리고 APPOINTMENT 테이블에서

2022년 4월 13일 취소되지 않은 흉부외과(CS) 진료 예약 내역을 조회하는 쿼리 작성

진료예약번호, 환자이름, 환자번호, 진료과코드, 의사이름, 진료예약일시 항목이 출력되도록 작성

결과는 진료예약일시를 기준으로 오름차순 정렬

 

 

 

문제파악:

문제는 쉬워보였다.

그냥 테이블 2개 조인, 조인 반복하고, 조건 걸고, 정렬 후에 컬럼만 뽑아내면 되는 문제였고 그게 맞았다.

 

문제를 끝까지 제대로 잘 읽어야 한다.

취소되지 않은 진료 예약 내역을 조회하는 쿼리 작성이 아닌,

취소되지 않은 흉부외과(CS) 진료 예약 내역을 조회하는 쿼리 작성 이다.

 

당연히 이렇게 오해해 버리면 "흉부외과(CS) 진료 예약 내역" 이라는 예외조건을 빼먹고 쿼리를 작성하게 된다.


문제또한 모호하게 적혀있긴 하다.

 

"2022년 4월 13일 취소되지 않은 흉부외과(CS) 진료 예약 내역을 조회하는 쿼리 작성"

1) 나는 당연히 4월 13일에 취소되지 않은 진료예약내역을 조회하는 쿼리로 이해했는데,

 

문제에서 원하는 해석은,

2) 2022년 4월 13일의 예약건 중 취소되지 않은 건을 조회하는 것을 의미하는 것 같았다.

????? 저문장이 저렇게 해석된다고?

 

모호해도 상관없다.

저 문장이 어떻게 해석되든 나는 문제에 맞게 해석하고, 문제가 원하는 대로 풀어야만 한다.

완전히 다른 해석이라, 잘못 해석하면 괜히 시간이 끌릴 수 있으니 예시에 맞게 해석하는 것이 중요해 보였다.

 

글만 잘 읽고, 문장은 애매해도 예시에 맞게 잘 껴맞추면 충분히 쉽게 풀 수 있는 문제라 생각되었다.

 

 

 

문제풀이:

SELECT APNT_NO
     , PT_NAME
     , AP.PT_NO
     , AP.MCDP_CD
     , DR_NAME
     , AP.APNT_YMD

FROM APPOINTMENT AS AP
     INNER JOIN PATIENT AS PT ON PT.PT_NO = AP.PT_NO
     INNER JOIN DOCTOR AS DT ON DT.DR_ID = AP.MDDR_ID
     
WHERE AP.MCDP_CD ="CS"
AND APNT_YMD LIKE "2022-04-13%"
AND APNT_CNCL_YN = "N"
ORDER BY APNT_YMD ASC

 

쉬울 줄 알았는데, 어려운 문제

 

링크: https://school.programmers.co.kr/learn/courses/30/lessons/59413

 

습득한 점:

쉬운 줄 알았는데, 생각보다 어려운 문제였다. SET함수를 활용해 본적이 없었어서 그랬을 수도 있다.

풀이법을 외워버리면 될 것 같다. 이 문제를 통해 SET함수를 실제로 활용해 볼 수 있었음.

이 또한 With 구문으로 풀어볼려고 했지만, With 구문에 테이블 이름을 끌어옴을 명시하는데 있어서, 표기하기가 난해했다.

(내가 아직 부족한 걸 수도!!)

 

 

문제:

문제:

0시부터 23시까지, 각 시간대 별로 입양이 총 몇 건 일어났는지 파악하는 쿼리 작성.

결과는 시간대순으로 정렬.

 

 

 

문제파악:

열심히 case구문으로 풀었는데, 답이 나오지 않아 문제를 잘 살펴 보았더니
정답지에는 입양이 일어나지 않는 시간또한 나타나 있었다.
가령 0시 32분에 입양된 기록이 없다면, count=0으로 표시되어

hour count
0 0
1 0
2 3

 으로 표시되는 식이었다.

나의 쿼리는 당연히 입양이 일어난 시각만 셀 수 있도록 작성되어 있었다.

 

데이터베이스에는 없는 시간을 만드는 다른 방법을 생각해야만 했고,

SET 함수를 활용했다.

 

* SET함수의 경우, 어떤 변수에 특정 값을 넣어줄 때 사용한다. @와 변수명을 함께 사용하고,
* SET @HOUR = -1; 는, HOUR 변수 값을 -1 로 초기화 해주는 것과 같다.

다른 파이썬이나 자바에서의 변수초기화와 같다고 생각하면 될 것 같다.

* := 기호는 대입 연산자의 개념이다. HOUR = HOUR +1 >>> 우측에 계산된 값으로 좌측 값을 덮어 씌우는 형식.

 

* WHERE @HOUR < 23; 의 경우, 반복을 0부터 22까지 총 23번 한다고 생각하면 된다.

 

* 또한 아래 코드를 삽입해서, 

WHERE 조건에서 @HOUR 변수와 HOUR(DATETIME)의 값이 서로 같을때를 카운트하는 쿼리를 SELECT의 두번째 인자로 삽입한 뒤, COUNT라는 Alias를 붙인다.

(SELECT COUNT(*) 
FROM ANIMAL_OUTS 
WHERE HOUR(DATETIME) = @HOUR) AS COUNT

 

* @HOUR변수와 @HOUR(DATETIME)로 나타낸 시간이 같을 때를 카운트 하기때문에,

@HOUR(DATETIME)과 @HOUR변수 테이블이 순차적으로 함께 만들어지며 COUNT 더해나간다.

 

 

풀이: SET을 활용하는 쿼리를 작성 할때,    := 및 ;의 사용에 반드시 주의해야할 것 같다.

SET @HOUR = -1;
SELECT (@HOUR := @HOUR +1) AS HOUR
     , (SELECT COUNT(HOUR(DATETIME))
        FROM ANIMAL_OUTS
        WHERE HOUR(DATETIME)=@HOUR) AS COUNT
        FROM ANIMAL_OUTS
WHERE @HOUR < 23;

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/164673

 

1. 조인조건을 찾아보니 다들 Board_id로 조인했고,

나만 Writer_id 기준으로 묶었더라.

 

2. 쿼리 짜는 것은 쉬웠지만, 데이터 포맷을 바꾸는 것 같은 세부적인 작업에 아직 익숙하지 않아서 연습이 필요하다.

 

3. CREATED_DATE(댓글작성일) 기준으로 오름차순 정렬,

    댓글작성일이 같으면 TITLE(게시글 제목) 기준으로 오름차순 정렬이란 말에 어떻게 풀어야 할 지 살짝 멈칫.

    결과적으로 경우의 수는 같거나 다르냐 2가지 일 뿐인데, 댓글작성일이 같을 경우를 처리하는 쿼리를 어떻게 만들지 생각하고 있었다;;;

4. 문제 제대로 읽자. 쉬운 문제야

 

SELECT TITLE
     , B.BOARD_ID
     , REPLY_ID
     , R.WRITER_ID
     , R.CONTENTS
     , DATE_FORMAT(R.CREATED_DATE, '%Y-%m-%d') AS CREATED_DATE 
FROM USED_GOODS_BOARD AS B
    INNER JOIN USED_GOODS_REPLY AS R ON B.BOARD_ID = R.BOARD_ID

WHERE B.CREATED_DATE BETWEEN '2022-10-01' AND '2022-10-31'
ORDER BY R.CREATED_DATE, TITLE

 

 

문제 설명

다음은 중고거래 게시판 정보를 담은 USED_GOODS_BOARD 테이블과 중고거래 게시판 첨부파일 정보를 담은 USED_GOODS_REPLY 테이블입니다. USED_GOODS_BOARD 테이블은 다음과 같으며 BOARD_ID, WRITER_ID, TITLE, CONTENTS, PRICE, CREATED_DATE, STATUS, VIEWS은 게시글 ID, 작성자 ID, 게시글 제목, 게시글 내용, 가격, 작성일, 거래상태, 조회수를 의미합니다.


Column name Type Nullable
BOARD_ID VARCHAR(5) FALSE
WRITER_ID VARCHAR(50) FALSE
TITLE VARCHAR(100) FALSE
CONTENTS VARCHAR(1000) FALSE
PRICE NUMBER FALSE
CREATED_DATE DATE FALSE
STATUS VARCHAR(10) FALSE
VIEWS NUMBER FALSE

USED_GOODS_REPLY 테이블은 다음과 같으며 REPLY_ID, BOARD_ID, WRITER_ID, CONTENTS, CREATED_DATE는 각각 댓글 ID, 게시글 ID, 작성자 ID, 댓글 내용, 작성일을 의미합니다.


Column name Type Nullable
REPLY_ID VARCHAR(10) FALSE
BOARD_ID VARCHAR(5) FALSE
WRITER_ID VARCHAR(50) FALSE
CONTENTS VARCHAR(1000) TRUE
CREATED_DATE DATE FALSE

문제

USED_GOODS_BOARD와 USED_GOODS_REPLY 테이블에서 2022년 10월에 작성된 게시글 제목, 게시글 ID, 댓글 ID, 댓글 작성자 ID, 댓글 내용, 댓글 작성일을 조회하는 SQL문을 작성해주세요. 결과는 댓글 작성일을 기준으로 오름차순 정렬해주시고, 댓글 작성일이 같다면 게시글 제목을 기준으로 오름차순 정렬해주세요.


예시

USED_GOODS_BOARD 테이블이 다음과 같고

 

BOARD_ID WRITER_ID TITLE CONTENTS PRICE CREATED_DATE STATUS VIEWS
B0001 kwag98 반려견 배변패드 팝니다 정말 저렴히 판매합니다. 전부 미개봉 새상품입니다. 12000 2022-10-01 DONE 250
B0002 lee871201 국내산 볶음참깨 직접 농사지은 참깨입니다. 3000 2022-10-02 DONE 121
B0003 goung12 배드민턴 라켓 사놓고 방치만 해서 팝니다. 9000 2022-10-02 SALE 212
B0004 keel1990 디올 귀걸이 신세계강남점에서 구입. 정품 아닐시 백퍼센트 환불 130000 2022-10-02 SALE 199
B0005 haphli01 스팸클래식 팔아요 유통기한 2025년까지에요 10000 2022-10-02 SALE 121

 

USED_GOODS_REPLY 테이블이 다음과 같을 때

 

REPLY_ID BOARD_ID WRITER_ID CONTENTS CREATED_DATE
R000000001 B0001 s2s2123 구매하겠습니다. 쪽지 드립니다. 2022-10-02
R000000002 B0002 hoho1112 쪽지 주세요. 2022-10-03
R000000003 B0006 hwahwa2 삽니다. 연락주세요. 2022-10-03
R000000004 B0007 hong02 예약중 2022-10-06
R000000005 B0009 hanju23 구매완료 2022-10-07

 

SQL을 실행하면 다음과 같이 출력되어야 합니다.

 

TITLE BOARD_ID REPLY_ID WRITER_ID CONTENTS CREATED_DATE
반려견 배변패드 팝니다 B0001 R000000001 s2s2123 구매하겠습니다. 쪽지 드립니다. 2022-10-02
국내산 볶음참깨 B0002 R000000002 hoho1112 쪽지 주세요. 2022-10-03

 

 

 

-Reference

https://kig6022.tistory.com/7

FORMAT 설명
%M Month 월(Janeary, February ...)
%m Month 월(01, 02, 03 ...)
%W Day of Week 요일(Sunday, Monday ...)
%D Month 월(1st, 2dn, 3rd ...)
%Y Year 연도(1999, 2000, 2020)
%y Year 연도(99, 00, 20)
%X Year 연도(1999, 2000, 2020) %V와 같이쓰임
%x Year 연도(1999, 2000, 2020) %v와 같이쓰임
%a Day of Week요일(Sun, Mon, Tue ...)
%d Day 일(00, 01, 02 ...)
%e Day 일(0, 1, 2 ..)
%c Month(1, 2, 3 ..)
%b Month(Jen Feb ...)
%j n번째 일(100, 365)
%H Hour 시(00, 01, 24) 24시간 형태 
%h Hour 시(01, 02, 12) 12시간 형태
%I(대문자 아이) Hour 시(01, 02 12) 12시간 형태
%l(소문자 엘) Hour 시(1, 2, 12) 12 시간 형태
%i Minute 분(00, 01 59)
%r hh:mm:ss AP | PM
%T hh:mm:ss
%S, %s Second 초
%p AP, PM
%w Day Of Week (0, 1, 2) 0부터 일요일
%U Week 주(시작: 일요일)
%u Week 주(시작 월요일)
%V Week 주(시작: 일요일)
%v Week 주(시작:월요일)

 

+ Recent posts