묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결비전공자도 따라하는 워드프레스 홈페이지 제작
PC버전-모바일버전 수정 오류
안녕하세요. 강사님!먼저 좋은 강의 감사합니다.PC버전과 모바일 버전을 번갈아 가면서 강의 도중에 수정하시는데 저는 모바일 버전을 수정하고 오면 PC버전 레이아웃이 변경되어있습니다. 예를 들면 모바일 버전에서 Wordpress Menu로 바꾸고 Navigation Menu를 삭제하면 PC버전에도 삭제가 되어있습니다. 서로 따로따로 관리하고 꾸미고 싶은데 어떻게 설정해야할까요?
-
미해결설계독학맛비's 실전 Verilog HDL Season 2 (AMBA AXI4 완전정복)
protocol instance관련 질문입니다.
안녕하세요 맛비님 오랜만에 질문글을 올립니다.testbench상에서 확인할 때 편의를 위해 protocol instance를 도입해주신 점 감사합니다. 이 부분에서 하나 궁금한 점이 있습니다.protocol instance에서 #1, #2, #3..으로 나오는 부분이 waveform상 1cycle씩 delay되는 것을 확인할 수 있는데, 이 부분이 의미하는 바가 있을까요? 안녕하세요 🙂[1. 질문 챕터] : eg) 몇 장, 몇 분 몇 초 쯤. or 수강생 분들이 봤을 때 어디구나?! 할 수 있게 표기 부탁 드려요.[2. 질문 내용] : eg) 질문 내용을 자유롭게 작성해주시면 되겠습니다 🙂[3. 시도했던 내용, 그렇게 생각하는 이유] : eg) 설치영상은 이렇게 시도했는데 안되더라 or 본인의 생각을 적어주세요. (실습 내용 중에 이해가 안되거나 잘못된 내용이 있는데, 이러 이러한 근거로 나는 이렇게 생각합니다.) ================ 다음 내용은 읽어보시고 지우시면 됩니다.=================질문 내용을 작성해주실 때, 위의 3단계로 제가 이해할 수 있게 작성해주시면 정확한 답변을 드릴 수 있을 것 같아요!!현업자인지라 업무때문에 답변이 늦을 수 있습니다. (길어도 만 3일 안에는 꼭 답변드리려고 노력중입니다 ㅠㅠ)강의에서 다룬 내용들의 질문들을 부탁드립니다!! (설치과정, 강의내용을 듣고 이해가 안되었던 부분들, 강의의 오류 등등)이런 질문은 부담스러워요.. (답변거부해도 양해 부탁드려요)개인 과제, 강의에서 다루지 않은 내용들의 궁금증 해소, 영상과 다른 접근방법 후 디버깅 요청, 고민 상담 등..글쓰기 에티튜드를 지켜주세요 (저 포함, 다른 수강생 분들이 함께보는 공간입니다.)서로 예의를 지키며 존중하는 문화를 만들어가요.질문글을 보고 내용을 이해할 수 있도록 남겨주시면 답변에 큰 도움이 될 것 같아요. (상세히 작성하면 더 좋아요! )먼저 유사한 질문이 있었는지 검색해보세요.잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.==================
-
해결됨독하게 C를 배운 사람을 위한 선형 자료구조
AddNewNode 함수 구현시 질문입니다.
void AddNewNode(int age, char pszName, char pszPhone){USERDATA* pNewNode = (USERDATA*)malloc(sizeof(USERDATA));pNewNode->age = age;strcpy_s(pNewNode->name, sizeof(pNewNode->name), pszName);strcpy_s(pNewNode->phone, sizeof(pNewNode->phone), pszPhone);pNewNode->pNext = NULL;강사님 위 코드 볼드체부분에서 pNewNode 포인터값이 널값임에 따라 역참조 경고가 발생합니다.그러나 제 생각에는 malloc함수로 할당받은 힙메모리 주소가 담겨져 있을 것인데 왜 이런 오류가 발생하는지 궁금합니다.
-
미해결IT 회사에서 비개발자가 살아남기 위한 모든 개발 지식 A to Z
수업자료
수업자료 Notion 접속이 안되는데, 확인 부탁드립니다~
-
미해결
실행할때 로딩이 너무 길어요
해당 코드는 스프링 mvc1 10강 3분대 내용입니다. 코드를 적고 실행을 하는데 왼쪽 하단에 보면 계속 로딩중이 뜹니다. 이유가 뭘까요?
-
미해결실습으로 손에 잡히는 SQLD의 정석(2과목)
데이터베이스 접속이 안됩니다. ㅠ
데이터 베이스 접속시 무한 로딩이 됩니다. 되어서 다시 만들어보니 접속이 잘 되지 않습니다. 이유가 있을까요?(다른 데이터베이스는 접속이 잘됩니다.)로컬만 안붙는것 같은데 이유를 잘 모르겠네요
-
미해결[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
비동기 처리방식
1.비동기 처리방식중 future와 stream이 있다고 하는데 도서리뷰앱에서는 비동기 처리방식 중 future을 사용하는건가요? stream을 사용하는건가요?2.코드에서 await과 async을 사용한것을 봤을때 future방식인지 궁금합니다. 그리고 bloc이 stream 기반이라고 하는데 두가지 방식 다 사용된건지 궁금합니다.3.widget_test부분에 사용된 await도 비동기 처리방식 중 하나인건가요?
-
미해결이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
한글 코드 저장에 관하여 질문드립니다.
한글관련 코드를 작성하실때마다 UTF8로 인코딩 형식을 바꿔서 저장해주고 계신데,매번 바꾸는게 번거로워혹시 기본 저장세팅을 UTF8로 하면 문제가 생기나요? 기본 인코딩을 UTF8로 하면 다른 단점이 있는지기본 인코딩을 UTF8로 바꾸는하는 것이 불가능한지?에 관하여 질문드리고 싶습니다.강의 잘 보고 있습니다. 감사합니다.
-
미해결홍정모의 따라하며 배우는 C언어
string data가 어느 메모리 영역에 저장 되는지 헷갈려서요..
안녕하세요. 11.2 메모리 레이아웃과 문자열 11:38문자열은 읽기전용 데이터 세그먼트에 저장된다고 이해했는데요,4:50에 문자열 데이터는 프로그램 코드영역에 저장된다 설명하는데 둘중에 어느곳에 저장되는건지 궁금해요!
-
해결됨10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
3-I 질문있습니다!
코드 리뷰를 한번 보고 로직을 작성했는데처음에는 이 방식으로 작성했습니다if (visited[(turn+1) % 2][next]) continue;visited[(turn+1) % 2][next] = visited[(turn) % 2][now] + 1; 500000 0 을 입력했을 때 999가 나오면서 오답인데선생님 코드는if (visited[(turn) % 2][next]) continue;visited[(turn) % 2][next] = visited[(turn +1) % 2][now] + 1;으로 -1 나오면서 정답인데두 코드간의 차이를 모르겠습니다
-
미해결스프링 핵심 원리 - 기본편
Bean등록 부분이 이해가 안됩니다.
첫번쨰로 수동으로 등록한다고 했을때 package hello.core.config; import hello.core.discount.DiscountPolicy; import hello.core.discount.impl.FixDiscountPolicy; import hello.core.discount.impl.RateDiscountPoilcy; import hello.core.member.repository.MemberReposotory; import hello.core.member.repository.impl.MemoryMemberRepository; import hello.core.member.service.MemberService; import hello.core.member.service.impl.MemberServiceImpl; import hello.core.order.service.OrderService; import hello.core.order.service.impl.OrderSerivceImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } @Bean public OrderService orderService() { return new OrderSerivceImpl(discountPolicy(), memberRepository()); } @Bean public MemberReposotory memberRepository() { return new MemoryMemberRepository(); } @Bean public DiscountPolicy discountPolicy() { return new RateDiscountPoilcy(); // 또는 RateDiscountPolicy()로 변경 가능 } } 이런식으로 @Configuration + @Bean으로 수동으로 등록하면 package hello.core.member.service.impl; import hello.core.member.domain.Member; import hello.core.member.repository.MemberReposotory; import hello.core.member.repository.impl.MemoryMemberRepository; import hello.core.member.service.MemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; //@Component public class MemberServiceImpl implements MemberService { // private final MemberReposotory memberReposotory = new MemoryMemberRepository(); private final MemberReposotory memberReposotory; public MemberServiceImpl(MemberReposotory memberReposotory) { this.memberReposotory = memberReposotory; } @Override public void join(Member member) { memberReposotory.save(member); } @Override public Member findMemer(Long memerId) { return memberReposotory.findById(memerId); } public MemberReposotory getMemberReposotory() { return memberReposotory; } }MemberSeriveImpl클래스에는 @Component를 안붙여도되는거죠? 두번째 질문은 제가 알기론 컴포넌트스켄을 사용안하고 Component만 클래스위에붙여도 자동적으로 빈으로 등록되는걸로아는데 꼭 ComponentScan을 적용해야만 Component가붙은 클래스들이 자동적으로 빈으로 등록되나요?
-
미해결이득우의 언리얼 프로그래밍 Part4 - 게임플레이 어빌리티 시스템
빌드오류가 계속 나옵니다
vs 도구를 추가로 설치하거나 generate를 계속해주거나일반 프로젝트를 생성하고 source랑 contents를 넣은 뒤 generate를 해줘도 동일합니다강의자료로 해도 깃헙에서 받아도 전부 그렇습니다
-
해결됨태블로 지도 시각화, 기초부터 고급까지
브이월드 지도
안녕하세요. 드디어 마지막 섹션을 듣고 있습니다.알려주신 네이버 블로그에서 브이월드 지도를 가져다 쓰려고 하는데요. 작성일이 2020년인데 현재는 2024년이니 지도에 변화가 있을텐데, 알려주신 지도는 최신화 반영되어 있나요?
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
자기자신을 추가해도 문제가 없는거같아 질문드립니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.여기에서 public static void main(String[] args) { Scanner in = new Scanner(System.in); String input1 = in.nextLine(); Integer size = Integer.valueOf(input1); int[][] input2 = new int[Integer.valueOf(input1) ][Integer.valueOf(input1) ]; for (int i = 0; i < Integer.valueOf(input1); i++) { String[] temp = in.nextLine().split(" "); for (int j = 0; j < temp.length; j++) { input2[i ][j] = Integer.valueOf(temp[j]); } } int[] count = new int[size]; // 학생 번호 -> [V][] // 학년 -> [][V] // 자기자신 번호를 추가해도 문제X for (int i = 0; i < size; i++) { boolean[] matched = new boolean[size]; // 학년 for (int j = 0; j < size; j++) { int now = input2[i][j]; // 학생 for (int k = 0; k < size; k++) { int another = input2[k][j]; if (now == another){ matched[k] = true; } } } int matchedCount = 0; for (int j = 0; j < size; j++) { if (matched[j]){ matchedCount++; } } count[i] = matchedCount; } int max = 0; int maxStu = 0; for (int i = 0; i < size; i++) { if (count[i] > max){ maxStu = i; } } System.out.println(maxStu); }어차피 자기자신은 항상 포함되어 기본값이 1이게될텐데,boolean[] matched = new boolean[size]; 에서 체크하는걸로 처리하였습니다.이접근법이 틀린이유를 모르겠습니다.1. 자기자신을 같이처리 (기본카운트는 항상 1부터)2. 리스트에 매치된 학생들을 계산 후 마지막에 더함
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
@Transactional 적용되는 접근제어자 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]강의에서 @Transactional 애노테이션이 붙여있어도 public이 아니면 AOP가 적용이안된다고하고 V1 테스트의 internal에서 public을 지우고 했을때 적용이안된다고하셨는데 저는 public을 지워도 되더라고요 @Test void internalCall(){ callService.internal(); } @Transactional void internal(){ log.info("call internal"); printTxInfo(); } 결과화면 이유를 알고싶습니다.Dependencies관련 build.gradle 버전 plugins { id 'java' id 'org.springframework.boot' version '3.3.5' id 'io.spring.dependency-management' version '1.1.6' } group = 'hello' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } tasks.named('test') { useJUnitPlatform() }
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
Actuator busrefresh 관련 질문
해결 했습니다. 강의 감사합니다
-
미해결[코드팩토리] [초급] 8시간만에 끝내는 코드팩토리의 Typescript 완전정복 풀코스
리플렉션과 데코레이터 사용시 의문점
안녕하세요리플렉션과 데코레이터를 공부하면서 잘 이해한건지 궁금합니다. const restrictParamValueKey = Symbol('restrict-param-value') interface RestrictionInfo<T> { index: number restrictValues: T[] } function RestrictParamValue<T>(restrictValues: T[]) { return (target: any, propertyKey: string, index: number) => { console.log(`${target} ${propertyKey}${index}`) const prevMeta = Reflect.getOwnMetadata(restrictParamValueKey, target, propertyKey) ?? [] const info: RestrictionInfo<T> = { index, restrictValues } Reflect.defineMetadata(restrictParamValueKey, [ ...prevMeta, info ], target, propertyKey) console.log(Reflect.getOwnMetadata(restrictParamValueKey, target, propertyKey)) } }메서드의 파라미터 데코레이터 사용시 Reflect.defineMetadata로 메타데이터를 정의하는데 3번째 파라미터로 target 4번째로는 propertyKey를 넣는 이유가 target는 클래스의 프로토타입 이며 propertyKey는 메서드가 target 클래스의 프로토타입의 메서드이기 때문일까요?추가로 메서드 데코레이터와 파라미터 데코레이터에서의 target, propertyKey는 동일한게 맞을까요?
-
해결됨김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션
섹션12의 HTTP 서버1 - 시작에서 27분에 질문있습니다.
다른 브라우저를 사용해야 테스트가 확실히 된다고 하셨는데같은 브라우저일 때는 왜 테스트에 어려움이 있는걸까요?어차피 쓰레드 하나로 순차 동기 실행 아닐까요?궁금합니다!
-
미해결
[빠짝스터디 3주차 과제]리텐션 연습문제
리텐션 연습문제1. weekly retention을 구하는 쿼리를 바닥부터 스스로 작성해보기WITH event_log_base AS ( SELECT DISTINCT DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATE_TRUNC(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul'), WEEK(MONDAY)) AS event_week, DATE_TRUNC(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul'), MONTH) AS event_month, user_id, user_pseudo_id, event_name, platform, event_params FROM advanced.app_logs ), -- 사용자별 첫 방문 주차 계산 user_first_visit_base AS ( SELECT user_pseudo_id, MIN(event_week) OVER (PARTITION BY user_pseudo_id) AS first_visit_week, event_week AS current_week FROM event_log_base ), -- 사용자별 첫 방문 주차와 현재 주차 차이 계산 user_weekly_diff AS ( SELECT first_visit_week, DATE_DIFF(current_week, first_visit_week, WEEK) AS week_diff, COUNT(DISTINCT user_pseudo_id) AS weekly_active_users FROM user_first_visit_base GROUP BY first_visit_week, week_diff ) -- 유지율 계산 SELECT first_visit_week, week_diff, weekly_active_users, SAFE_DIVIDE(weekly_active_users, FIRST_VALUE(weekly_active_users) OVER (PARTITION BY first_visit_week ORDER BY week_diff ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS retention_rate FROM user_weekly_diff; 리텐션 연습문제2. Retain user를 New + Current + Resurrected + Dormant user로 나누는 쿼리 작성군집별 분류기준1. 신규 사용자 (New User)는 시스템에 처음으로 등록되거나 서비스를 처음으로 사용한 이후 30일 이내에 활동한 사용자. 첫 방문 날짜(first_visit_date)와 마지막 방문 날짜(last_visit_date) 간의 차이가 30일 이하일 경우 ‘신규 사용자’로 분류2. 현재 사용자 (Current User)는 서비스에 처음 등록한 후 30일이 지난 사용자 중, 최근 30일 이내에도 서비스에 접속한 기록이 있는 사용자. 첫 방문 날짜와 마지막 방문 날짜의 차이가 30일을 초과하고, 가장 최근 이벤트 날짜(latest_event_date)로부터 30일 이내에 활동한 경우 ‘현재 사용자’로 분류3. 휴면 사용자 (Dormant User)는 한동안 서비스를 이용하지 않아서, 마지막 방문 이후 현재까지 30일 이상 비활동 상태에 있는 사용자. 사용자의 마지막 방문 날짜(last_visit_date)가 가장 최근 이벤트 날짜로부터 30일 이상 경과했을 경우 ‘휴면 사용자’로 분류4. 복귀 사용자 (Resurrected User)는 일정 기간(30일 이상) 동안 비활동 상태였으나, 다시 서비스를 사용하기 시작한 사용자. 사용자 활동 기록에서 비활성화 기간이 30일 이상 지속되었다가 다시 활동이 발생한 경우(이전 방문 이후 30일 동안 활동이 없다가 다시 방문 시), 해당 사용자를 ‘복귀 사용자’로 분류WITH event_data AS ( SELECT DISTINCT DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, user_pseudo_id FROM advanced.app_logs ), -- 사용자별 첫 방문 및 마지막 방문 날짜 계산 user_first_last_visit AS ( SELECT user_pseudo_id, MIN(event_date) AS first_visit_date, MAX(event_date) AS last_visit_date FROM event_data GROUP BY user_pseudo_id ), -- 앱 로그의 마지막 이벤트 날짜 계산 current_event_date AS ( SELECT MAX(event_date) AS latest_event_date FROM event_data ), -- 사용자의 이벤트 활동을 기준으로 휴면 여부 계산 user_activity_log AS ( SELECT user_pseudo_id, event_date, LEAD(event_date) OVER (PARTITION BY user_pseudo_id ORDER BY event_date) AS next_event_date, CASE WHEN DATE_DIFF(LEAD(event_date) OVER (PARTITION BY user_pseudo_id ORDER BY event_date), event_date, DAY) > 30 THEN 1 ELSE 0 END AS inactive_period FROM event_data ), -- 사용자 유형 분류: 신규, 현재, 휴면, 복귀 사용자 user_category AS ( SELECT u.user_pseudo_id, u.first_visit_date, u.last_visit_date, ced.latest_event_date, MAX(ual.inactive_period) AS inactive_period, CASE WHEN DATE_DIFF(ced.latest_event_date, u.last_visit_date, DAY) > 30 THEN 'dormant_user' WHEN DATE_DIFF(u.last_visit_date, u.first_visit_date, DAY) <= 30 THEN 'new_user' WHEN MAX(ual.inactive_period) = 1 THEN 'resurrected_user' ELSE 'current_user' END AS user_type FROM user_first_last_visit AS u CROSS JOIN current_event_date AS ced LEFT JOIN user_activity_log AS ual ON u.user_pseudo_id = ual.user_pseudo_id GROUP BY u.user_pseudo_id, u.first_visit_date, u.last_visit_date, ced.latest_event_date ), -- 주차별 사용자 유형과 첫 방문 주차와의 차이 계산 user_weekly_retention AS ( SELECT uc.user_type, ed.user_pseudo_id, ed.event_date, DATE_DIFF(DATE_TRUNC(ed.event_date, WEEK(MONDAY)), DATE_TRUNC(uc.first_visit_date, WEEK(MONDAY)), WEEK) AS week_difference FROM event_data AS ed JOIN user_category AS uc ON ed.user_pseudo_id = uc.user_pseudo_id ), -- 사용자 유형 및 주차별 사용자 수 계산 user_count_by_type_and_week AS ( SELECT user_type, week_difference, COUNT(DISTINCT user_pseudo_id) AS user_count FROM user_weekly_retention GROUP BY user_type, week_difference ), -- 유지율 계산 retention_calculation AS ( SELECT user_type, week_difference, user_count, FIRST_VALUE(user_count) OVER (PARTITION BY user_type ORDER BY week_difference) AS initial_user_count FROM user_count_by_type_and_week ) SELECT user_type, week_difference, ROUND(SAFE_DIVIDE(user_count, initial_user_count), 2) AS retention_rate FROM retention_calculation ORDER BY user_type, week_difference; 리텐션 연습문제3. 주어진 데이터에서 어떤 사람들이 리텐션이 그나마 높은지 찾아보기-- 1) 특정 월에 방문한 사용자들의 월별 리텐션 비교 -- 첫 접속일을 기준으로 리텐션이 높은 코호트를 분석하여, 리텐션 높은 사용자들이 특정 시기와 관련이 있는지 확인 WITH monthly_event_base AS ( SELECT user_pseudo_id, DATE_TRUNC(MIN(event_date) OVER (PARTITION BY user_pseudo_id), MONTH) AS first_event_month, DATE_TRUNC(event_date, MONTH) AS current_month, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime FROM advanced.app_logs ), -- 첫 방문 월 대비 차이 계산 monthly_diff_data AS ( SELECT user_pseudo_id, first_event_month, current_month, DATE_DIFF(current_month, first_event_month, MONTH) AS month_diff FROM monthly_event_base ORDER BY month_diff ), -- 월별 사용자 수 계산 monthly_user_count AS ( SELECT first_event_month, month_diff, COUNT(DISTINCT user_pseudo_id) AS user_count FROM monthly_diff_data GROUP BY first_event_month, month_diff ORDER BY month_diff ) -- 리텐션 비율 계산 SELECT *, ROUND(SAFE_DIVIDE(user_count, initial_user_count), 2) AS retention_rate FROM ( SELECT *, FIRST_VALUE(user_count) OVER (PARTITION BY first_event_month ORDER BY month_diff) AS initial_user_count FROM monthly_user_count ) ORDER BY first_event_month, month_diff; -- 2) 특정 이벤트가 높은 리텐션과 관련이 있는가 -- 사용자별 주요 이벤트의 단계와 횟수를 파악하여 리텐션 높은 사용자들이 특정 행동 패턴을 보이는지 확인 WITH event_base AS ( SELECT user_pseudo_id, DATE_TRUNC(MIN(event_date) OVER (PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, DATE_TRUNC(MIN(event_date) OVER (PARTITION BY user_pseudo_id), MONTH) AS first_month, event_name, param FROM advanced.app_logs CROSS JOIN UNNEST(event_params) AS param ), -- 이벤트별 단계 및 세션 정보 추출 event_stage AS ( SELECT user_pseudo_id, first_week, first_month, event_name, MAX(IF(param.key = "firebase_screen", param.value.string_value, NULL)) AS firebase_screen, MAX(IF(param.key = "food_id", param.value.string_value, NULL)) AS food_id, MAX(IF(param.key = "session_id", param.value.string_value, NULL)) AS session_id FROM event_base GROUP BY user_pseudo_id, first_week, first_month, event_name ORDER BY user_pseudo_id ), -- 퍼널 단계별 사용자 수 계산 funnel_stage_count AS ( SELECT first_month, CASE WHEN event_name = "screen_view" THEN 1 WHEN event_name = "click_login" THEN 2 WHEN event_name = "click_search" THEN 3 WHEN event_name = "request_search" THEN 4 WHEN event_name = "click_restaurant" THEN 5 WHEN event_name = "click_food_category" THEN 6 WHEN event_name = "view_recommend_extra_food" THEN 7 WHEN event_name = "click_cart" THEN 8 WHEN event_name = "click_payment" THEN 9 WHEN event_name = "click_banner" THEN 10 END AS step_number, event_name, COUNT(DISTINCT user_pseudo_id) AS count FROM event_stage GROUP BY first_month, event_name HAVING step_number IS NOT NULL ORDER BY first_month, step_number ) -- 단계별 퍼널 비율 계산 SELECT *, ROUND(SAFE_DIVIDE(count, previous_step_count), 2) AS funnel_ratio FROM ( SELECT *, LAG(count) OVER (PARTITION BY first_month ORDER BY step_number) AS previous_step_count FROM funnel_stage_count ) ORDER BY first_month, step_number; 첫째, 10월과 11월에 첫 방문한 사용자가 다른 월에 비해 리텐션이 높게 나타났으며, click_food_category 이벤트를 거친 사용자의 리텐션이 높았다.리텐션 연습문제4. core event를 "click_payment"라고 설정하고 weekly retention 구하기 WITH user_payment_data AS ( SELECT user_pseudo_id, event_date, DATE_TRUNC(MIN(event_date) OVER (PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_event_week, DATE_TRUNC(event_date, WEEK(MONDAY)) AS current_event_week, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime FROM advanced.app_logs WHERE event_name = 'click_payment' ), -- 첫 이벤트 주차 대비 현재 주차 차이 계산 weekly_difference_data AS ( SELECT user_pseudo_id, first_event_week, current_event_week, DATE_DIFF(current_event_week, first_event_week, WEEK) AS weeks_since_first_event FROM user_payment_data ORDER BY weeks_since_first_event ), -- 주차별 사용자 수 집계 weekly_user_counts AS ( SELECT first_event_week, weeks_since_first_event, COUNT(DISTINCT user_pseudo_id) AS user_count FROM weekly_difference_data GROUP BY first_event_week, weeks_since_first_event ORDER BY weeks_since_first_event ) -- 주차별 리텐션 비율 계산 SELECT *, ROUND(SAFE_DIVIDE(user_count, initial_user_count), 2) AS retention_rate FROM ( SELECT *, FIRST_VALUE(user_count) OVER (PARTITION BY first_event_week ORDER BY weeks_since_first_event) AS initial_user_count FROM weekly_user_counts ) ORDER BY first_event_week, weeks_since_first_event;
-
미해결
[빠짝스터디 3주차 과제] 1~3번 문제
1번 문제. 주차별 각 카테고리별 평균 할인율이 가장 높았던 기간과 할인율을 구하는 쿼리 작성WITH transaction_data AS ( SELECT 111 AS user_id, 1001 AS item_id, 719200 AS actual_price, '01/08/2024 12:00:00' AS transaction_date UNION ALL SELECT 111, 2002, 89000, '01/10/2024 12:00:00' UNION ALL SELECT 189, 2002, 89000, '01/12/2024 12:00:00' UNION ALL SELECT 156, 3002, 459000, '01/15/2024 12:00:00' UNION ALL SELECT 121, 1001, 719200, '01/18/2024 12:00:00' UNION ALL SELECT 156, 2001, 90300, '01/25/2024 12:00:00' UNION ALL SELECT 145, 3001, 399000, '01/26/2024 12:00:00' UNION ALL SELECT 189, 1002, 607200, '01/28/2024 12:00:00' UNION ALL SELECT 111, 3001, 399000, '02/05/2024 12:00:00' UNION ALL SELECT 178, 1002, 759000, '02/07/2024 12:00:00' UNION ALL SELECT 121, 2002, 62300, '02/08/2024 12:00:00' UNION ALL SELECT 156, 1001, 899000, '02/10/2024 12:00:00' UNION ALL SELECT 190, 2001, 90300, '02/11/2024 12:00:00' UNION ALL SELECT 189, 2001, 90300, '02/14/2024 12:00:00' UNION ALL SELECT 111, 1002, 759000, '02/15/2024 12:00:00' UNION ALL SELECT 156, 3001, 299250, '02/20/2024 12:00:00' UNION ALL SELECT 189, 3002, 344250, '02/25/2024 12:00:00' UNION ALL SELECT 111, 2001, 90300, '02/28/2024 12:00:00' ), user_info AS ( SELECT 111 AS user_id, 'Seoul' AS city, 28 AS age, 'Female' AS gender UNION ALL SELECT 121, 'Busan', 35, 'Male' UNION ALL SELECT 145, 'Incheon', 42, 'Female' UNION ALL SELECT 156, 'Seoul', 31, 'Male' UNION ALL SELECT 178, 'Daegu', 25, 'Female' UNION ALL SELECT 189, 'Seoul', 39, 'Male' UNION ALL SELECT 190, 'Busan', 29, 'Female' ), item_info AS ( SELECT 1001 AS item_id, 'Electronics' AS category, 'Smartphone' AS item_name, 899000 AS list_price UNION ALL SELECT 1002 AS item_id, 'Electronics' AS category, 'Tablet' AS item_name, 759000 AS list_price UNION ALL SELECT 2001 AS item_id, 'Fashion' AS category, 'Sneakers' AS item_name, 129000 AS list_price UNION ALL SELECT 2002 AS item_id, 'Fashion' AS category, 'Backpack' AS item_name, 89000 AS list_price UNION ALL SELECT 3001 AS item_id, 'Home' AS category, 'Coffee Machine' AS item_name, 399000 AS list_price UNION ALL SELECT 3002 AS item_id, 'Home' AS category, 'Air Purifier' AS item_name, 459000 AS list_price ), -- 거래 데이터에 datetime 형식 적용 transaction_base AS ( SELECT user_id, item_id, actual_price, PARSE_DATETIME('%m/%d/%Y %H:%M:%S', transaction_date) AS transaction_datetime FROM transaction_data ), -- 할인율 계산 및 주별 그룹화 discount_data AS ( SELECT transaction_base.user_id, transaction_base.item_id, 100 - (transaction_base.actual_price / item_info.list_price) * 100 AS discount_ratio, transaction_base.transaction_datetime, item_info.category, DATE_TRUNC(transaction_base.transaction_datetime, WEEK) AS transaction_week FROM transaction_base LEFT JOIN item_info ON transaction_base.item_id = item_info.item_id ), -- 카테고리별 주차 평균 할인율 계산 weekly_discount_avg AS ( SELECT FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', transaction_week) AS transaction_week, category, AVG(discount_ratio) AS avg_discount_ratio FROM discount_data GROUP BY transaction_week, category ), -- 카테고리별 최고 평균 할인율 주차 및 할인율 찾기 category_discount_rank AS ( SELECT transaction_week, category, avg_discount_ratio, RANK() OVER(PARTITION BY category ORDER BY avg_discount_ratio DESC) AS rank FROM weekly_discount_avg ) -- 최종 결과 출력 SELECT transaction_week, category, avg_discount_ratio AS highest_avg_discount_ratio FROM category_discount_rank WHERE rank = 1 ORDER BY category; 2번 문제. 2024년 1월에 가장 많은 매출을 기록한 카테고리를 구하는 쿼리 작성WITH transaction_data AS ( SELECT 111 AS user_id, 1001 AS item_id, 719200 AS actual_price, '01/08/2024 12:00:00' AS transaction_date UNION ALL SELECT 111, 2002, 89000, '01/10/2024 12:00:00' UNION ALL SELECT 189, 2002, 89000, '01/12/2024 12:00:00' UNION ALL SELECT 156, 3002, 459000, '01/15/2024 12:00:00' UNION ALL SELECT 121, 1001, 719200, '01/18/2024 12:00:00' UNION ALL SELECT 156, 2001, 90300, '01/25/2024 12:00:00' UNION ALL SELECT 145, 3001, 399000, '01/26/2024 12:00:00' UNION ALL SELECT 189, 1002, 607200, '01/28/2024 12:00:00' UNION ALL SELECT 111, 3001, 399000, '02/05/2024 12:00:00' UNION ALL SELECT 178, 1002, 759000, '02/07/2024 12:00:00' UNION ALL SELECT 121, 2002, 62300, '02/08/2024 12:00:00' UNION ALL SELECT 156, 1001, 899000, '02/10/2024 12:00:00' UNION ALL SELECT 190, 2001, 90300, '02/11/2024 12:00:00' UNION ALL SELECT 189, 2001, 90300, '02/14/2024 12:00:00' UNION ALL SELECT 111, 1002, 759000, '02/15/2024 12:00:00' UNION ALL SELECT 156, 3001, 299250, '02/20/2024 12:00:00' UNION ALL SELECT 189, 3002, 344250, '02/25/2024 12:00:00' UNION ALL SELECT 111, 2001, 90300, '02/28/2024 12:00:00' ), user_info AS ( SELECT 111 AS user_id, 'Seoul' AS city, 28 AS age, 'Female' AS gender UNION ALL SELECT 121, 'Busan', 35, 'Male' UNION ALL SELECT 145, 'Incheon', 42, 'Female' UNION ALL SELECT 156, 'Seoul', 31, 'Male' UNION ALL SELECT 178, 'Daegu', 25, 'Female' UNION ALL SELECT 189, 'Seoul', 39, 'Male' UNION ALL SELECT 190, 'Busan', 29, 'Female' ), item_info AS ( SELECT 1001 AS item_id, 'Electronics' AS category, 'Smartphone' AS item_name, 899000 AS list_price UNION ALL SELECT 1002 AS item_id, 'Electronics' AS category, 'Tablet' AS item_name, 759000 AS list_price UNION ALL SELECT 2001 AS item_id, 'Fashion' AS category, 'Sneakers' AS item_name, 129000 AS list_price UNION ALL SELECT 2002 AS item_id, 'Fashion' AS category, 'Backpack' AS item_name, 89000 AS list_price UNION ALL SELECT 3001 AS item_id, 'Home' AS category, 'Coffee Machine' AS item_name, 399000 AS list_price UNION ALL SELECT 3002 AS item_id, 'Home' AS category, 'Air Purifier' AS item_name, 459000 AS list_price ), -- 1월 데이터 필터링 및 카테고리별 매출 합계 계산 january_sales_data AS ( SELECT trans.actual_price, item.category FROM transaction_data AS trans LEFT JOIN item_info AS item ON trans.item_id = item.item_id WHERE trans.transaction_date >= '01/01/2024' AND trans.transaction_date < '02/01/2024' ) -- 카테고리별 매출 합계 계산 및 순위 설정 SELECT category, total_sales FROM ( SELECT category, SUM(actual_price) AS total_sales, RANK() OVER(ORDER BY SUM(actual_price) DESC) AS sales_rank FROM january_sales_data GROUP BY category ) AS ranked_sales WHERE sales_rank = 1; 3번 문제. 유저별 총 구매 금액이 200만원 이상인 유저들이 가장 많이 구매한 카테고리를 찾는 쿼리 작성WITH transaction_data AS ( SELECT 111 AS user_id, 1001 AS item_id, 719200 AS actual_price, '01/08/2024 12:00:00' AS transaction_date UNION ALL SELECT 111, 2002, 89000, '01/10/2024 12:00:00' UNION ALL SELECT 189, 2002, 89000, '01/12/2024 12:00:00' UNION ALL SELECT 156, 3002, 459000, '01/15/2024 12:00:00' UNION ALL SELECT 121, 1001, 719200, '01/18/2024 12:00:00' UNION ALL SELECT 156, 2001, 90300, '01/25/2024 12:00:00' UNION ALL SELECT 145, 3001, 399000, '01/26/2024 12:00:00' UNION ALL SELECT 189, 1002, 607200, '01/28/2024 12:00:00' UNION ALL SELECT 111, 3001, 399000, '02/05/2024 12:00:00' UNION ALL SELECT 178, 1002, 759000, '02/07/2024 12:00:00' UNION ALL SELECT 121, 2002, 62300, '02/08/2024 12:00:00' UNION ALL SELECT 156, 1001, 899000, '02/10/2024 12:00:00' UNION ALL SELECT 190, 2001, 90300, '02/11/2024 12:00:00' UNION ALL SELECT 189, 2001, 90300, '02/14/2024 12:00:00' UNION ALL SELECT 111, 1002, 759000, '02/15/2024 12:00:00' UNION ALL SELECT 156, 3001, 299250, '02/20/2024 12:00:00' UNION ALL SELECT 189, 3002, 344250, '02/25/2024 12:00:00' UNION ALL SELECT 111, 2001, 90300, '02/28/2024 12:00:00' ), user_info AS ( SELECT 111 AS user_id, 'Seoul' AS city, 28 AS age, 'Female' AS gender UNION ALL SELECT 121, 'Busan', 35, 'Male' UNION ALL SELECT 145, 'Incheon', 42, 'Female' UNION ALL SELECT 156, 'Seoul', 31, 'Male' UNION ALL SELECT 178, 'Daegu', 25, 'Female' UNION ALL SELECT 189, 'Seoul', 39, 'Male' UNION ALL SELECT 190, 'Busan', 29, 'Female' ), item_info AS ( SELECT 1001 AS item_id, 'Electronics' AS category, 'Smartphone' AS item_name, 899000 AS list_price UNION ALL SELECT 1002 AS item_id, 'Electronics' AS category, 'Tablet' AS item_name, 759000 AS list_price UNION ALL SELECT 2001 AS item_id, 'Fashion' AS category, 'Sneakers' AS item_name, 129000 AS list_price UNION ALL SELECT 2002 AS item_id, 'Fashion' AS category, 'Backpack' AS item_name, 89000 AS list_price UNION ALL SELECT 3001 AS item_id, 'Home' AS category, 'Coffee Machine' AS item_name, 399000 AS list_price UNION ALL SELECT 3002 AS item_id, 'Home' AS category, 'Air Purifier' AS item_name, 459000 AS list_price ), -- 사용자별 총 구매 금액 계산 및 200만원 이상 필터링 user_total_purchase AS ( SELECT user_id, SUM(actual_price) AS total_purchase_amount FROM transaction_data GROUP BY user_id HAVING total_purchase_amount >= 2000000 ), -- 필터링된 유저의 카테고리별 구매 금액 합계와 순위 계산 category_sales_rank AS ( SELECT item_info.category AS category, SUM(transaction_data.actual_price) AS total_category_sales, RANK() OVER(ORDER BY SUM(transaction_data.actual_price) DESC) AS sales_rank FROM transaction_data LEFT JOIN item_info ON transaction_data.item_id = item_info.item_id WHERE transaction_data.user_id IN ( SELECT user_id FROM user_total_purchase ) GROUP BY category ) -- 결과 출력 SELECT category, total_category_sales FROM category_sales_rank WHERE sales_rank = 1;