프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

문제 자체는 어렵지 않은데 여러 버전으로 풀어본 기록! (이라서 숨김처리 안함)

 


 

1. 가장 처음에 생각나는 기본 풀이법 - Group By와 Having으로 조건 넣기

SELECT B.BOOK_ID AS BOOK_ID
    , A.AUTHOR_NAME AS AUTHOR_NAME
    , DATE_FORMAT(B.PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK B
JOIN AUTHOR A
ON (B.AUTHOR_ID = A.AUTHOR_ID)
GROUP BY CATEGORY, BOOK_ID
HAVING CATEGORY = '경제'
ORDER BY PUBLISHED_DATE
;

 

👉 업무 하면서 '모든 데이터를 조인시키면 성능이 떨어진다'는 말을 많이 들었기에, 지금과 같이 전체 데이터를 모두 조인하지말고 좀더 나은 방법이 없을까 생각하게 됐다. 모든 데이터 조인 & 그룹을 두개나 & 거기서 경제로 걸러지는 상황.

 

 

2. where조건을 쓴다면?

SELECT B.BOOK_ID AS BOOK_ID
    , A.AUTHOR_NAME AS AUTHOR_NAME
    , DATE_FORMAT(B.PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK B
JOIN AUTHOR A
ON (B.AUTHOR_ID = A.AUTHOR_ID)
WHERE CATEGORY = '경제'
GROUP BY CATEGORY, BOOK_ID
ORDER BY PUBLISHED_DATE
;

 

👉 HAVING조건은 사라졌지만 순서상 조인 다음에 WHERE이 들어가므로 여전히 전체데이터를 모두 조인시킨다는 문제

가 남아있다. 

 

 

3. 해당하는 데이터만 조인처리 한다면?

SELECT B.BOOK_ID AS BOOK_ID
    , A.AUTHOR_NAME AS AUTHOR_NAME
    , DATE_FORMAT(B.PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK B
JOIN AUTHOR A
ON (B.AUTHOR_ID = A.AUTHOR_ID AND B.CATEGORY= '경제')
GROUP BY CATEGORY, BOOK_ID
ORDER BY PUBLISHED_DATE

 

👉 조인 조건을 추가해서 '경제' 카테고리만 처리했지만 조건이 눈에 잘 띄지않는다는 단점아닌 단점(?)이 있기도 하다.

개인적으로는 제일 간단하면서도 깔끔하다고 생각.

 

 

4. CTE를 활용한다면?

WITH CTE AS (
    SELECT BOOK_ID
        , DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
        , AUTHOR_ID
        , CATEGORY
    FROM BOOK
    WHERE CATEGORY = '경제'
) SELECT CTE.BOOK_ID AS BOOK_ID
    , A.AUTHOR_NAME AS AUTHOR_NAME
    , CTE.PUBLISHED_DATE AS PUBLISHED_DATE
FROM CTE
JOIN AUTHOR A
ON (CTE.AUTHOR_ID = A.AUTHOR_ID) 
GROUP BY CATEGORY, BOOK_ID
ORDER BY PUBLISHED_DATE

 

👉변환작업하면서 오라클과의 성능차이로😂어쩔수 없이 CTE가 필요한 순간들이 있는데, 이렇게 하면 WHERE조건으로 데이터를 거르면서 조인도 처리할 수 있어서 써봤다. 하지만 CTE자체가 성능에 베스트는 아니라서 이 방법이 효율적이라고 할 수 있을지는 모르겠다. 언제 한번 더미데이터로 실행계획도 확인해봐야겠다.

 

이제 출근준비 고고! 🏃‍♀️🏃‍♀️🏃‍♀️

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

1) JOIN만 잘 하면 될 문제라 생각해서 쉽게 풀었다 생각했는데, 자꾸 틀린 답이라고 해서 어리둥절했었다. 날짜도 잘 잡았고 GROUP BY, ORDER BY 다 잘했는데 왜?

-- 이 답이 틀린 이유는..?

SELECT YEAR(S.SALES_DATE) AS YEAR
    , MONTH(S.SALES_DATE) AS MONTH
    , I.GENDER AS GENDER
    , COUNT(S.USER_ID) AS USERS
FROM ONLINE_SALE S 
    JOIN USER_INFO I ON (S.USER_ID = I.USER_ID)
WHERE I.GENDER IS NOT NULL
GROUP BY YEAR
    , MONTH
    , GENDER
ORDER BY YEAR
    , MONTH
    , GENDER
;

 

 

2) 이런 문제들의 맹점. '동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.' 이 조건을 잘 생각해볼 필요가 있다. 날짜1에 회원1이 상품 1을 구매하는건 한개의 판매데이터이나, 여기서 뽑는 조건은 '월'단위 이므로 같은 달 날짜 2에 회원 1이 상품1 OR 상품2를 또 구매할 수 있다는 것. 그래서 COUNT를 할 때 DISTINCT를 해야 한다.

 

 

더보기
SELECT YEAR(S.SALES_DATE) AS YEAR
    , MONTH(S.SALES_DATE) AS MONTH
    , I.GENDER AS GENDER
    , COUNT(DISTINCT S.USER_ID) AS USERS
FROM ONLINE_SALE S 
    JOIN USER_INFO I ON (S.USER_ID = I.USER_ID)
WHERE I.GENDER IS NOT NULL
GROUP BY YEAR
    , MONTH
    , GENDER
ORDER BY YEAR
    , MONTH
    , GENDER
;

 

 

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

Oracle과 MySQL은 날짜 포맷 방법이 다르다는점에 유의.

Oracle MySql
TO_CHAR(날짜, 포맷) 
YYYY 2024
YY 24
MM 03
DD 21
DATE_FORMAT(날짜,  포맷)
%Y 2024
%y 24
%M January
%m 03
%D 1st 2nd 3rd..22th..31st
%d

 

 

더보기
-- ORACLE VER.
SELECT
    ANIMAL_ID
    , NAME
    , TO_CHAR(DATETIME, 'YYYY-MM-DD') AS 날짜
FROM
    ANIMAL_INS
ORDER BY
    ANIMAL_ID
;



-- MYSQL VER.
SELECT
    ANIMAL_ID
    , NAME
    , DATE_FORMAT(DATETIME, '%Y-%m-%d') AS 날짜
FROM
    ANIMAL_INS
ORDER BY
    ANIMAL_ID
;

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

1) 생성해준 이름을 group by로 가져다 쓰기.

더보기
SELECT
    SUBSTR(PRODUCT_CODE, 1, 2) AS CATEGORY
    , COUNT(PRODUCT_ID) AS PRODUCTS
FROM
    PRODUCT
GROUP BY
    CATEGORY
ORDER BY 
    CATEGORY
;

 

 

 group by를 할때, 묶어주는 이름이 group by에 없으면 alias로 설정한 이름도 가져다 쓴다는 이야기를, 어제 스터디그룹에서 팀원들에게 설명해줬었는데 마침 그런 문제가 있어서 풀어봤다.

 

order by가 가져다 쓰는거야 순서가 select문 다음이니까 그렇다 쳐도, group by가 select문 전에 작동하는데 어떻게 가져다써 ? ← 이 부분을 이해하는게 포인트인듯!

 

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

1. 한글자씩 읽어오도록 하기 - 어제 썼던 toCharArray()외에 string builder를 쓸 수 있을까? 생각해봄

2. n개만큼 반복시키기 - for외에 다른걸로 반복시킬 방법이 있을까?라고 생각해보면 while은 더 비효율적일것 같고.

3. 출력하기

 

 

 

 

1. 아는대로 풀기

더보기
class Solution {
    public String solution(String my_string, int n) {
        String answer ="";
        
        for(char c : my_string.toCharArray()){
            for(int i=0; i<n; i++)
                answer+=c;
        }
        return answer;
    }
}

 

어제 풀이의 연장선이라 크게 달라진게 없다.... 이중포문을 벗어나고 싶은데.

 

 

 

2. String builder를 쓸 수 있을까?

더보기
public class Programmers {

	public static void main(String[] args) {
		String my_string = "hello";
		int n = 3;
		String answer = "";

		StringBuilder sb = new StringBuilder();

		for (char c : my_string.toCharArray())
			sb.append((c+"").repeat(n));
		answer = sb.toString();

		System.out.println(answer);
	}
}

 

String java.lang.String.repeat(int count)

Returns a string whose value is the concatenation of this string repeated count times.

If this string is empty or count is zero then the empty string is returned.

- Parameters:count number of times to repeatReturns: A string composed of this string repeated count times or the empty string if this string is empty or count is zero

- Throws:IllegalArgumentException - if the count is negative.Since: 11

 

자료구조에서도 push()같이 넣는작업을 반복해서도 글자를 넣던데, 유사하게 쓸 수 있지 않을까? append를 돌려야하나? 라는 의문이 있었고, 싱글스레드인 경우에는 String 객체를 새로 만들고 연결하는 작업을 생략할 수 있는 String builder를 쓰는게 좋다.고 개념적으로만 알고있어서, 쓸수 있는지 생각을 했는데...

조리법을 모르겠어서 다른분 정답에서 힌트를 얻어 써보았다.

 

이때 repeat()메서드는 string builder에서 활용할 수 있는 메서드가 아니라, String이 문자열을 반복할 수 있도록 자바 11부터 추가된 메서드였음! 

 

repeat관해서 찾다보니 왜 이렇게 해야하는지 알고리즘적으로 해설이 된 블로그를 보게 되었는데... 으으 갈길이 멀다

 

 

java string repeat 메서드로 쉽게 문자열을 반복해 봅시다.

카톡방에서 python은 'abc' * 5와 같은 문법이 있는데 자바에는 없는지 물어보셨습니다. java 8에서는 어떻게 쓰는지 잘 모르겠습니다. 아마, 이런 식으로 쓰지 않을까 싶습니다. "abc"를 10번 반복하기

codingdog.tistory.com

 

 

 

 

+ Recent posts