묻고 답해요
147만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
순위 정보를
불러오고 있어요
-
미해결[플러터플로우]코딩 없이 한 달 만에 앱 만들기
간단하게 조건 설정하기 (Conditional) 파트 오류
이거 이렇게 뜨는데 어떻게 해결할 수 있나요?
-
미해결Flutter로 SNS 앱 만들기
마치면서 에러가 댓글가져오기와 좋아요 리스트 가져오기 에러
마치면서.. 에러가 댓글가져오기와 좋아요 리스트 가져오기 에러.두개가 에러 발생되어 해결방법을 몰라서 강사님의 깃을 다운받아서 댓글과 좋아요 에러 나는 곳을 확인하니 제가 누락된 코드인지 추가된코드인지 알수는 없지만 에러가 많아서 접어두고, 강사님 코드로 돌려보았으나 이런창이 뜨네요. 완성은 하고싶은데..어렵네요..어떻게 해야할지..?혹시나 싶어서 적어봅니다dart 3.5.4flutter 3.24.5Android Studio Ladybug | 2024.2.1 Patch 2
-
미해결Flutter로 SNS 앱 만들기
섹션15페이징기능_4프로필 화면에 페이징 적용
섹션15페이징기능_4프로필 화면에 페이징 적용에서프로필 화면은 잘 작동 합니다그러나,좋아요 리스트는 여전히 동작 안하고 있어요.
-
해결됨[Unity] 함께 만들어가는 방치형 게임 개발
파이어베이스로 가챠시스템을 연동시키는 것과 관련해 질문드립니다
안녕하세요! 강의를 시청하면서 가챠시스템을 배웠는데요다름이 아니라 클라이언트에서만 가챠시스템을 운용한다면 위조나 보안에 취약하다는 생각이 들었습니다따라서 앞서 배운 강의내용인 파이어베이스와 연동을 해서가챠시스템을 연동하면 좋겠단 생각을 했는데그럴 경우, 어떤 식으로 내용을 구성해야 효율적으로 관리할 수 있을지의견을 여쭙고자 합니다.
-
해결됨[Unity] 함께 만들어가는 방치형 게임 개발
안녕하세요 소스코드를 다운 받고 싶은데요.. 언제 제공 받을 수 있을까요?
안녕하세요. 게임 구현 중에서 일부분적으로 이해가 안되는 부분이 있어서 강의 학습을 시작하였습니다.다 따라쳐서 하는 기초 목적으로 수강하지 않아서, 일단 유니티 에디터에서 플레이는 되게하고 응용해보고 싶은데요. 강의 종료 후 제공된다고 글이 있는 것 같은데요.. 지금 커리큘럼이 출시?로 보이는데 다 끝난건지, 소스 코드가 언제 제공되는지 궁금합니다 ...
-
미해결Flutter로 SNS 앱 만들기
섹션15페이징기능_3좋아요 목록 화면에 페이징 적용
이페이지에서는 강의 없던 코드가 강의코드가 있고,갑자기 나오고, 이페이지에서는 정리가 안돼요. 또 실행도 잘안돼요.프로필화면에서도 6개 게시물인데 3개만가져오고, 좋아요 화면은 실행이 안돼고... 이페이지는다시 영상만들어야 할것 같아요
-
미해결Flutter로 SNS 앱 만들기
섹션14페이징기능_1게시글 목록 화면에 페이징 적용 feed_repository.dart에러
섹션14페이징기능_1게시글 목록 화면에 페이징 적용_feed_repository.dart에서 에러가 발생했습니다 그런데 예전에 좋아요에서 원본코드 (feed_repository.dart) getFeedList()부분QuerySnapshot<Map<String, dynamic>> snapshot = await firebaseFirestore.collection('feeds').where('uid', isEqualTo: uid).orderBy('createAt', descending: true).get(); 문제가 발생되어 다음과 같이 수정하여 동작아였으나 14페이징기능_게시글 목록 화면에 페이징 적용 하면서 어떻게 해야할지요Query<Map<String, dynamic>> query = await firebaseFirestore.collection('feeds').orderBy('createAt', descending: true); if (uid != null) {query = query.where('uid', isEqualTo: uid); } QuerySnapshot<Map<String, dynamic>> snapshot = await query.get();
-
미해결Flutter로 SNS 앱 만들기
11셕션에서 좋아요.강의코드에서 좋아요 업데이트 문제 제대로 수정된건가요
11셕션에서 좋아요.강의코드에서 좋아요 업데이트문제발생.사용자 유저가 feedScreen에서좋아요 버튼을 누르고,좋아요 바 버튼을 누루면 좋아요누른 게시물이 표시되나,앱을 종료하고, 다시 접속해서 좋아요 바 버튼을 누르면 좋아요게시물이 재대로 찍히지 않습니다.그래서, 다음 같이 수정하니 그런문제가 사라졌습니다제가 올바르게 수정한건가요 }) async { try { // 강의코드 에러 //Map<String, dynamic> userMapData = await firebaseFirestore // .collection('users') // .doc(uid) // .get() // .then((value) => value.data()!); //userMapData['likes'];// 다이나믹으로 반환됨 //List<String> likes = List<String>.from( // userMapData['Likes']); //문자열로 반환받은 List // 수정코드 DocumentReference<Map<String, dynamic>> userMapDataDocRef = firebaseFirestore.collection('users').doc(uid); DocumentSnapshot<Map<String, dynamic>> userMapDataSnapshot = await userMapDataDocRef.get(); List<String> likes = List<String>.from(userMapDataSnapshot.data()!['likes']); // 수정코드끝
-
미해결코딩 몰라도 OK! CursorAI로 시작하는 개발 생활 (웹/초급)
실습 강의에서 node.js설치법
안녕하세요. 실습 시작 강의에서 node.js설치법이 강의 노트에 있다고 하는데, 안보여서 질문 드립니다.개인적으로 다운 받아 설치 코자 하는데, Docker, fnm 중에서 어떤 걸 선택해야 하는지 모르겠네요혹, 제가 노트에서 못 찾고 있다면 노트 위치를 설명해 주심 감사하겠습니다. 답변 부탁드립니다.
-
미해결Flutter로 SNS 앱 만들기
12댓글화면_3댓글정보 가져오기
logger.d(currentUserModel);콘솔에서는 찍고 있습니다그러나 logger.d(commentState.commentList);콘솔에서 못찍고 있습니다
-
미해결Flutter로 SNS 앱 만들기
11댓글화면_댓글 정보 가져오기에서 콘솔에 commentList못찍고 있어요
16:09//변환해서 가져오기 List<CommentModel> commentModel = await Future.wait(snapshot.docs.map( (e) async { Map<String, dynamic> data = e.data(); logger.d(data); DocumentReference<Map<String, dynamic>> writerDocRef = data['writer']; logger.d(writerDocRef); 데이터를 가져오질 못해서 콘솔에 찍어봤습니다 logger.d(data); 잘 찍고 있으나 logger.d(writerDocRef); 이거는 못찍고 있어요
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
프로필 수정 후 변경된 내용을 피드에 바로 반영되도록 하고 싶습니다.
안녕하세요. 강의 유익하게 들었습니다!지금 마지막까지 강의를 다 듣고 코드 작성도 완료한 상태인데, 현재는 ProfileEditingView에서 정보 수정 후, 피드에 수정된 유저의 정보가 바로 반영되지 않는 상태입니다.저는 프로필 수정 후 피드에 수정된 유저 정보가 바로 반영 되도록 추가적으로 작업을 하려고 하는데, 가장 최선의 방법이 무엇일지 궁금합니다. 현재로선 FeedCellView에 .onAppear를 걸어서 내부에 유저 정보를 한 번 더 가져오는 식으로 작성하거나, 아니면 새로고침을 했을 때만 가져오는 방법을 생각했는데, 이렇게 하면 모든 게시물에서 유저 정보를 업데이트 해야해서 그만큼 딜레이가 많이 발생하는 문제점이 있어 또 다른 나은 방법이 있을지, 이게 최선인지 알고싶습니다! 감사합니다.
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 4주차] 최종 과제
노션 링크 첨부합니다.https://focapa.notion.site/4-141094a2b89980b080c6e19f8b5c4a48?pvs=4
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝 스터디 최종 과제] 6-1의 최종 과제
https://www.notion.so/yijin87/Foodie-4-1430181a6e9b808c9426fb5475909a23?pvs=4 노션링크로 대체합니다.
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 4주차 과제] 강의 6-1의 최종 과제
노션으로 작성하여 링크 첨부합니다.https://sapphire-spade-aa6.notion.site/1435677c375480a997e3d8bf961008dd
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 3주차 과제] 리텐션 연습 문제
6주차 과제 - 1) Weekly Retention을 구하는 쿼리를 바닥부터 스스로 작성해보세요 with base as ( select distinct user_pseudo_id , event_name , date(datetime(timestamp_micros(event_timestamp),'Asia/Seoul')) AS event_date from advanced.app_logs where event_date between '2022-08-01' and '2022-11-01' ) , retention_base as ( select distinct date_trunc(event_date, week(monday)) as event_week , min(date_trunc(event_date , week(monday)) ) over(partition by user_pseudo_id order by event_date)as first_week , user_pseudo_id from base ) , middle as ( select event_week , first_week , date_diff(event_week, first_week, day) as diff , user_pseudo_id from retention_base ) , final as ( select diff , count(distinct user_pseudo_id) as user_cnt from middle group by all ) select diff , first_value(user_cnt) over(order by diff asc) as first_visit_users , user_cnt , round((user_cnt/first_value(user_cnt) over(order by diff asc)), 2) from final - 2) Retain User를 New + Current + Resurrected + Dormant User로 나누는 쿼리를 작성해보세요. --한달내 유저가 얼마나 많은 이벤트를 발생시키는지? --지속적으로 사용한다의 정의를 이벤트를 고려할 것인지 아니면 방문만 볼것인지 신규 유저(New) : 제품을 처음 사용하는 유저 --각 달에 첫 로그를 남긴 유저 기존 유저(Current) : 제품을 지속적으로 사용하는 유저 --한달내에 복귀 유저(Resurrected) : 과거에 사용 -> 비활성 -> 다시 제품을 사용한 유저 휴면 유저(Dormant) : 일정 기간 제품을 사용하지 않은 비활성화 사용자 --해당 주 이외에 - 3) 주어진 데이터에서 어떤 사람들이 리텐션이 그나마 높을까요? 찾아보세요 --함께 고민해보면 좋을 가이드라인 - 휴면 유저를 어떻게 복귀 유저로 부활시킬 수 있을까? - 어떻게 신규 유저를 계속 늘릴 수 있을까? - 기존 유저가 감소하지 않으려면 어떻게 해야할까? - 4) Core Event를 “click_payment”라고 설정하고 Weekly Retention을 구해주세요 with base as ( select distinct user_pseudo_id , event_name , date(datetime(timestamp_micros(event_timestamp),'Asia/Seoul')) AS event_date , min(date_trunc(datetime(timestamp_micros(event_timestamp),'Asia/Seoul') , week(monday)) ) over(partition by user_pseudo_id order by event_week)as first_all_week from advanced.app_logs where event_date between '2022-08-01' and '2022-11-01' ) , retention_base as ( select distinct -- extract(event_date from week) as event_week , min(date_trunc(event_date , week(monday)) ) over(partition by user_pseudo_id order by event_week)as first_week -- , date_trunc(min(event_date) over(partition by user_pseudo_id), week(monday)) as first_week , date_trunc(event_date, week(monday)) as event_week , user_pseudo_id from base where event_name = “click_payment” ) , middle as ( select event_week , first_week , date_diff(event_week, first_week, day) as diff , user_pseudo_id from retention_base ) , weeks as ( select distinct first_week from base ) , final as ( select diff , min(first_week) as first_Week , count(distinct user_pseudo_id) as user_cnt from middle group by all ) select diff , first_value(user_cnt) over(order by diff asc) as first_visit_users , user_cnt , round((user_cnt/first_value(user_cnt) over(order by diff asc)). , 2) --safe_divide() 사용하면 좋음 from final1번 문제(15분)주차별 각 카테고리별 평균 할인율이 가장 높았던 기간과 할인율을 구하는 쿼리를 작성해주세요단, 날짜 데이터를 YYYY-MM-DD 23:59:39 이런 형태로 변경해주세요with raw as (select a.user_id , a.item_id , a.actual_price 90 , b.category , b.list_price 100 , (b.list_price-a.actual_price)/ b.list_price as discount , a.transaction_date from transaction_data a left join item_info b on a.item_id=b.item_id ) select FORMAT_TIMESTAMP('%Y-%m-%d 23:59:59', TIMESTAMP(DATE_TRUNC(DATE(transaction_date), WEEK(MONDAY)))) AS week_start_date, -- 주차의 월요일 날짜를 “YYYY-MM-DD 23:59:59” 형식으로 변환 , category , avg(discount) as avg_discount from raw group by 1,2 order 3 desc limit 1 2번 문제(10분)2024년 1월에 가장 많은 매출을 기록한 카테고리를 구하는 쿼리를 작성해주세요with raw as (select a.user_id , a.item_id , a.actual_price 90 , b.category , b.list_price 100 , (b.list_price-a.actual_price)/ b.list_price as discount , a.transaction_date from transaction_data a left join item_info b on a.item_id=b.item_id where extract(month from a.transaction_date) = 1 and extract(year from a.transaction_date) = 2024 ) select category , sum(actual_price) as gmv from raw group by 1 order gmv desc limit 1 3번 문제(10분)유저별 총 구매 금액이 200만원 이상인 유저들이 가장 많이 구매한 카테고리를 찾는 쿼리를 작성해주세요with raw as (select a.user_id , a.item_id , a.actual_price , b.category , b.list_price , a.transaction_date , sum(a.actual_price) over(partition by user_id) as user_gmv from transaction_data a left join item_info b on a.item_id=b.item_id where ) select category , count(item_id) as cnt_item , count(distinct item_id) as cnt_item , sum(actual_price) as gmv from raw where user_gmv group by 1 order 2 desc --가장많이의 정의가 구매건수라면 order 3 desc --가장많이의 정의가 유니크한 상품수라면 order 4 desc --가장많이의 정의가 gmv 매출이라면 limit 1
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 4주차 과제] 강의 6-1의 최종과제
https://ambiguous-serpent-eb1.notion.site/4-6-1-10208045473b80789c2ccd0823506890
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[인프런 빅쿼리 빠짝스터디 3주차] 리텐션 연습문제
1. Weekly RetentionWITH 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_visit_base AS ( SELECT user_pseudo_id, MIN(event_week) OVER (PARTITION BY user_pseudo_id) AS first_visit_week, event_week AS visit_week FROM base ), user_visit_weekdiff AS ( SELECT first_visit_week, DATE_DIFF(visit_week, first_visit_week, week) AS week_diff, COUNT(DISTINCT user_pseudo_id) AS visit_users FROM user_visit_base GROUP BY ALL ) SELECT first_visit_week, week_diff, visit_users, SAFE_DIVIDE(visit_users, FIRST_VALUE(visit_users) OVER (PARTITION BY first_visit_week ORDER BY week_diff ASC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS retention FROM user_visit_weekdiff 2. Retain User → New User, Current User, Resurrected User, Dormant User-- 한 달(30일)을 기준으로 구분하였다. -- 신규 유저: 최근 한 달 이내 새로 방문 -- 기존 유저: 최근 한 달 이내 재방문, 그 이전 한달에도 방문 -- 복귀 유저: 최근 한 달 이내 재방문, 그 이전 한달에는 방문 X -- 휴먼 유저: 최근 한 달 이내 재방문 X WITH base AS ( SELECT DISTINCT DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, user_pseudo_id FROM advanced.app_logs ), user_first_last AS ( SELECT user_pseudo_id, MIN(event_date) AS first_date, MAX(event_date) AS last_date FROM base GROUP BY user_pseudo_id ), last_event_date AS ( SELECT MAX(event_date) AS current_date FROM base ), user_activity 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 dormant_history FROM base ), user_types AS ( SELECT u.user_pseudo_id, u.first_date, u.last_date, led.current_date, MAX(us.dormant_history) AS dormant_history, CASE WHEN DATE_DIFF(led.current_date, u.last_date, DAY) > 30 THEN 'dormant_user' WHEN DATE_DIFF(u.last_date, u.first_date, DAY) <= 30 THEN 'new_user' WHEN MAX(us.dormant_history) = 1 THEN 'resurrected_user' ELSE 'current_user' END AS user_type FROM user_first_last AS u CROSS JOIN last_event_date AS led LEFT JOIN user_activity AS us ON u.user_pseudo_id = us.user_pseudo_id GROUP BY u.user_pseudo_id, u.first_date, u.last_date, led.current_date ), first_week_and_diff AS ( SELECT ut.user_type, fw.user_pseudo_id, fw.event_date, DATE_DIFF(DATE_TRUNC(fw.event_date, WEEK(MONDAY)), DATE_TRUNC(ut.first_date, WEEK(MONDAY)), WEEK) AS diff_of_week FROM base AS fw JOIN user_types AS ut ON fw.user_pseudo_id = ut.user_pseudo_id ), user_cnt_by_type_and_week AS ( SELECT user_type, diff_of_week, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM first_week_and_diff GROUP BY user_type, diff_of_week ), retention_base AS ( SELECT user_type, diff_of_week, user_cnt, FIRST_VALUE(user_cnt) OVER (PARTITION BY user_type ORDER BY diff_of_week) AS first_user_cnt FROM user_cnt_by_type_and_week ) SELECT user_type, diff_of_week, ROUND(SAFE_DIVIDE(user_cnt, first_user_cnt), 2) AS retention_rate FROM retention_base ORDER BY user_type, diff_of_week 3. retention이 높은 그룹?current user: 최고 0.41 (4~5주차)new user: 최고 0.11 (1,3주차)resurrected user: 최고 0.14 (9~12주차)dormant user: 최고 0.09 (3주차)리텐션이 그나마 높은 그룹: current usercurrent user, resurrected user 리텐션 분포의 경우 상승세 → 하강세 경향성을 보여 피크를 찍을 때 즈음 어떤 이벤트가 있었다고도 추측할 수 있다. 4. click_payment 이벤트를 중점으로 본 Weekly Retention?WITH base AS ( SELECT DISTINCT DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime, event_name, user_id, user_pseudo_id FROM advanced.app_logs WHERE 1=1 AND event_name = "click_payment" ), event_week_and_first_week AS ( SELECT DISTINCT DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week, user_pseudo_id, DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id ORDER BY event_date), WEEK(MONDAY)) AS first_week FROM base ), retention_base AS ( SELECT *, FIRST_VALUE(user_cnt) OVER(ORDER BY day_of_week) AS total_user FROM ( SELECT DATE_DIFF(event_week, first_week, WEEK) AS day_of_week, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM event_week_and_first_week GROUP BY day_of_week ) ) SELECT day_of_week, ROUND(SAFE_DIVIDE(user_cnt, total_user), 2) AS retention FROM retention_base ORDER BY day_of_week
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[빠짝스터디 4주차 과제] 최종 과제
SELECT DISTINCT LEFT(FORMAT_DATE('%Y%m%d', event_date), 6) AS login_month, COUNT(DISTINCT user_pseudo_id) as count FROM advanced.app_logs GROUP BY LEFT(FORMAT_DATE('%Y%m%d', event_date), 6)2022년 8월부터 2023년 1월까지의 MAU를 살펴보니(MAU기준은 로그인 기록), 첫 달인 2022년 8월에는 미진했지만 그 후로 점차 증가하는 것을 볼 수 있습니다. 특히 9월은 8월 대비 2배에 가까운 성장률을 보였고 10월에는 1.5배 이상의 성장률을 보이면서 점차 사용자가 확대되고 있는 것을 알 수 있습니다. WITH base AS ( SELECT DISTINCT user_pseudo_id, DATE_TRUNC(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul'), WEEK(MONDAY)) AS event_week, DATE_TRUNC(MIN(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week FROM `advanced.app_logs` ), first_week_diff AS ( SELECT user_pseudo_id, DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week FROM base ), user_counts AS ( SELECT diff_of_week, COUNT(DISTINCT user_pseudo_id) AS user_count FROM first_week_diff GROUP BY diff_of_week ) SELECT diff_of_week, user_count, ROUND(SAFE_DIVIDE(user_count, FIRST_VALUE(user_count) OVER (ORDER BY diff_of_week ASC)), 2) AS retention_rate FROM user_counts ORDER BY diff_of_week;주 리텐션율을 살펴보면, 첫 주에는 당연히 1%이지만 그 후로 확연히 주마다 접속하는 사용자가 줄고 있습니다. Foodie Express는 아직 Product Market Fit을 발견하지 못한 것으로 보입니다. WITH base AS ( SELECT DISTINCT user_id, user_pseudo_id, event_name, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul')) AS event_date, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime FROM advanced.app_logs WHERE event_date BETWEEN '2022-08-01' AND '2022-12-31' -- 데이터 길게보기 ), first_week_and_diff AS ( SELECT *, DATE_DIFF(event_week,first_week, WEEK) AS weeks_after_first_week FROM ( SELECT DISTINCT user_pseudo_id, DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week FROM base ) ), active_users AS( SELECT first_week, weeks_after_first_week, COUNT(DISTINCT user_pseudo_id) AS avtive_users FROM first_week_and_diff GROUP BY first_week, weeks_after_first_week ) SELECT first_week, weeks_after_first_week, avtive_users, FIRST_VALUE(avtive_users) OVER(PARTITION BY first_week ORDER BY weeks_after_first_week) AS cohort_users FROM active_users AS a ORDER BY first_week, weeks_after_first_week; 첫 주에 1,211의 사용자가 있었으나 1주차에 32명으로 급감했습니다 (약 2.6% 유지)2-8주차에는 비교적으로 안정적이었고, 9주차에서 20주에는 사용자가 좀 더 증가하였습니다.특히 14주차에 142명으로 가장 많은 사용자가 있었습니다. 이를 살펴보면, 초기에 감소 후에 오히려 사용자 수가 증가하는 패턴을 보이고오히려 앱을 사용하면 사용할 수록 더 활발하게 앱을 사용하는 것을 알 수 있습니다.따라서 어떻게든 사용자들을 앱에 유입시켜서 사용하게 만들어야합니다. 특히 주말, 공휴일 또는 음식 주문이 많은 근무 시간 이후에 비활성 사용자에게 정기적인 푸시 알림이나 메시지를 보내면 좋을 것 같습니다. (음식을 많이 시켜먹는 주말이나, 공휴일 또는 퇴근시간때쯤 맞춰서 푸시알림을 준다)공휴일에 좀 더 사용자가 증가하는 경향을 보이는 것 같은데, 이 때는 사용자 유입이 많으므로 소액 할인 쿠폰을 제공하는 것이 효과적일 것이라고 판단됩니다.무엇보다도 정기적인 알림을 통해 앱 사용 습관을 들이는 것이 중요해 보입니다!
-
해결됨BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
[인프런 빅쿼리 빠짝스터디 3주차] 3주차 과제
1번WITH -- 1단계: 필수 데이터만 추출하기 base_events AS ( SELECT user_pseudo_id, DATE(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul") AS event_date FROM advanced.app_logs ), -- 2단계: 사용자별 첫 방문 주차와 각 활동 주차 구하기 user_weeks AS ( SELECT DISTINCT -- 중복 제거 user_pseudo_id, -- 사용자별 첫 방문 주차 (월요일 기준) DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, -- 실제 방문한 주차 (월요일 기준) DATE_TRUNC(event_date, WEEK(MONDAY)) AS visit_week FROM base_events ), -- 3단계: 첫 방문 이후 몇 주차인지 계산하기 week_numbers AS ( SELECT user_pseudo_id, -- 첫 방문 이후 경과된 주차 계산 DATE_DIFF(visit_week, first_week, WEEK) AS week_number FROM user_weeks -- 최대 12주까지만 분석 WHERE DATE_DIFF(visit_week, first_week, WEEK) <= 12 ), -- 4단계: 주차별 총 사용자 수 계산하기 weekly_users AS ( SELECT week_number, COUNT(DISTINCT user_pseudo_id) AS user_count FROM week_numbers GROUP BY week_number ) -- 5단계: 최종 리텐션 계산하기 SELECT week_number, user_count as active_users, FIRST_VALUE(user_count) OVER(ORDER BY week_number) as first_week_users, ROUND(100.0 * user_count / FIRST_VALUE(user_count) OVER(ORDER BY week_number), 2) as retention_rate FROM weekly_users ORDER BY week_number; 2번WITH -- 1단계: 사용자별 주차 데이터 준비 user_weeks AS ( SELECT DISTINCT user_pseudo_id, -- 첫 방문 주차 DATE_TRUNC(MIN(DATE(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul")) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, -- 활동 주차 DATE_TRUNC(DATE(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul"), WEEK(MONDAY)) AS event_week FROM advanced.app_logs ), -- 2단계: 사용자 상태 확인 user_status AS ( SELECT user_pseudo_id, event_week, first_week, -- 이전 방문 주차 LAG(event_week) OVER(PARTITION BY user_pseudo_id ORDER BY event_week) AS prev_week FROM user_weeks ), -- 3단계: 상태 분류 weekly_status AS ( SELECT event_week, user_pseudo_id, CASE WHEN event_week = first_week THEN 'New' WHEN DATE_DIFF(event_week, prev_week, WEEK) = 1 THEN 'Current' WHEN DATE_DIFF(event_week, prev_week, WEEK) > 1 THEN 'Resurrected' END as user_type FROM user_status ), -- 4단계: 각 주차별 전체 유저 수 total_users AS ( SELECT fwd.event_week, COUNT(DISTINCT user_pseudo_id) AS total_user_count FROM user_status CROSS JOIN (SELECT DISTINCT event_week FROM user_weeks) AS fwd WHERE first_week <= fwd.event_week GROUP BY event_week ), -- 5단계: 주차별 활성 유저 수 계산 active_users AS ( SELECT event_week, COUNTIF(user_type = 'New') AS new_users, COUNTIF(user_type = 'Current') AS current_users, COUNTIF(user_type = 'Resurrected') AS resurrected_users, COUNT(DISTINCT user_pseudo_id) AS retain_users FROM weekly_status GROUP BY event_week ) -- 6단계: 최종 결과 SELECT FORMAT_DATE('%Y-%m-%d', a.event_week) as week_start, new_users, current_users, resurrected_users, (t.total_user_count - a.retain_users) as dormant_users, ROUND(100.0 * current_users / NULLIF(LAG(new_users) OVER(ORDER BY a.event_week), 0), 1) as retention_rate, retain_users as active_users, t.total_user_count as total_users FROM active_users a JOIN total_users t ON a.event_week = t.event_week ORDER BY a.event_week; 3번WITH -- 1단계: 기본 데이터 준비 user_weeks AS ( SELECT DISTINCT user_pseudo_id, DATE_TRUNC(MIN(DATE(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul")) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, DATE_TRUNC(DATE(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul"), WEEK(MONDAY)) AS event_week FROM advanced.app_logs ), -- 2단계: 사용자별 방문 주차 수 계산 user_visit_frequency AS ( SELECT user_pseudo_id, COUNT(DISTINCT event_week) as total_visit_weeks, DATE_DIFF(MAX(event_week), MIN(event_week), WEEK) + 1 as weeks_since_first, MIN(event_week) as first_visit_week FROM user_weeks GROUP BY user_pseudo_id ), -- 3단계: 사용자별 리텐션 점수 계산 user_retention_score AS ( SELECT user_pseudo_id, total_visit_weeks, weeks_since_first, ROUND(100.0 * total_visit_weeks / weeks_since_first, 2) as visit_rate, FORMAT_DATE('%Y-%m', first_visit_week) as cohort_month FROM user_visit_frequency WHERE weeks_since_first >= 4 -- 최소 4주 이상 경과된 사용자만 ), -- 4단계: 사용자 행동 데이터 분석 user_behavior AS ( SELECT r.user_pseudo_id, r.visit_rate, r.cohort_month, COUNT(DISTINCT DATE(TIMESTAMP_MICROS(l.event_timestamp), "Asia/Seoul")) as active_days, COUNT(DISTINCT l.event_timestamp) as total_events, COUNT(DISTINCT l.event_name) as unique_event_types FROM user_retention_score r JOIN advanced.app_logs l ON r.user_pseudo_id = l.user_pseudo_id GROUP BY r.user_pseudo_id, r.visit_rate, r.cohort_month ), -- 5단계: 리텐션 세그먼트별 행동 패턴 분석 retention_segments AS ( SELECT cohort_month, CASE WHEN visit_rate >= 75 THEN 'Very High (75%+)' WHEN visit_rate >= 50 THEN 'High (50-74%)' WHEN visit_rate >= 25 THEN 'Medium (25-49%)' ELSE 'Low (<25%)' END as retention_segment, COUNT(DISTINCT user_pseudo_id) as user_count, ROUND(AVG(visit_rate), 2) as avg_retention_rate, ROUND(AVG(active_days), 1) as avg_active_days, ROUND(AVG(total_events), 1) as avg_total_events, ROUND(AVG(unique_event_types), 1) as avg_unique_events FROM user_behavior GROUP BY cohort_month, CASE WHEN visit_rate >= 75 THEN 'Very High (75%+)' WHEN visit_rate >= 50 THEN 'High (50-74%)' WHEN visit_rate >= 25 THEN 'Medium (25-49%)' ELSE 'Low (<25%)' END ) -- 최종 결과 SELECT cohort_month, retention_segment, user_count, avg_retention_rate, avg_active_days, avg_total_events, avg_unique_events, ROUND(100.0 * user_count / SUM(user_count) OVER (PARTITION BY cohort_month), 2) as segment_percentage FROM retention_segments ORDER BY cohort_month, CASE retention_segment WHEN 'Very High (75%+)' THEN 1 WHEN 'High (50-74%)' THEN 2 WHEN 'Medium (25-49%)' THEN 3 WHEN 'Low (<25%)' THEN 4 END; 4번WITH -- 1단계: 결제 이벤트 기본 데이터 payment_base AS ( SELECT DISTINCT user_pseudo_id, DATE(TIMESTAMP_MICROS(event_timestamp), "Asia/Seoul") AS event_date FROM advanced.app_logs WHERE event_name = "click_payment" ), -- 2단계: 사용자별 첫 결제일과 주차 계산 user_weeks AS ( SELECT user_pseudo_id, -- 첫 결제 주차 DATE_TRUNC(MIN(event_date) OVER(PARTITION BY user_pseudo_id), WEEK(MONDAY)) AS first_week, -- 실제 결제 주차 DATE_TRUNC(event_date, WEEK(MONDAY)) AS event_week FROM payment_base ), -- 3단계: 주차별 상태 계산 week_status AS ( SELECT user_pseudo_id, event_week, first_week, -- 첫 주차와의 차이 DATE_DIFF(event_week, first_week, WEEK) AS week_number FROM user_weeks WHERE DATE_DIFF(event_week, first_week, WEEK) <= 12 -- 최대 12주까지만 분석 ), -- 4단계: 주차별 활성 사용자 수 계산 weekly_users AS ( SELECT week_number, COUNT(DISTINCT user_pseudo_id) AS active_users FROM week_status GROUP BY week_number ), -- 5단계: 첫 주 사용자 수 (코호트 크기) 구하기 first_week_users AS ( SELECT COUNT(DISTINCT user_pseudo_id) AS cohort_size FROM week_status WHERE week_number = 0 ) -- 최종 결과 SELECT week_number as week, active_users, cohort_size, ROUND(100.0 * active_users / cohort_size, 2) as retention_rate FROM weekly_users CROSS JOIN first_week_users ORDER BY week_number; 서비스 성장세총 사용자: 52,823명까지 증가8월부터 12월까지 꾸준한 성장10월에 가장 높은 신규 유저 유입 (4,048명)리텐션 개선전체 리텐션: 8월 2.6% → 1월 48%로 큰 폭 개선12월부터 40% 이상의 안정적인 리텐션 유지재방문 사용자 비중이 지속적으로 증가 개선 필요점결제 리텐션이 매우 낮음 (1% 수준)신규 사용자 유입이 감소 추세휴면 사용자가 지속적으로 증가
주간 인기글
순위 정보를
불러오고 있어요