안녕하세요~! 영한님 category_path 를 생성하는 과정에서 idx_descendant 인덱스를 생성하는데요. descendant_id 는 외래키로 설정해서 인덱스가 자동으로 생성되지 않나요?! 아래 쿼리를 실행했을 때 index 가 생성되는 것을 확인 했습니다! create table category_path ( ancestor_id bigint not null, -- 조상 노드 descendant_id bigint not null, -- 자손 노드 depth int not null, -- 거리 (깊이 차이) primary key (ancestor_id, descendant_id), foreign key (ancestor_id) references category_closure(category_id), foreign key (descendant_id) references category_closure(category_id) ); create index idx_depth on category_path(depth); show indexes from category_path; create index idx_descendant on category_path(descendant_id); 위와 같이 명시적으로 인덱스를 생성한 이유가 있을까요? 감사합니다.
학습 관련 질문만 남겨주세요. 강의자에 대한 질문은 안받습니다(eg. 대학원 가실 생각은 없으신가요? , 데이터분석가는 어떻게 하게 되신거에요?) 포트폴리오는 노션, ppt, github 중 어떤게 가장 효율적일까요? 혹시 제가 수행했던 프로젝트 관련해서 어디까지 포트폴리오에 넣으면 좋을지 이메일 상담가능한가요??
안녕하세요 JOIN 연습문제 1번에 대해서 질문이 있습니다 SELET kor_name, COUNT( tp.id ) AS pokemon_cnt 와 SELET kor_name, COUNT( p.id ) AS pokemon_cnt 출력되는 행의 개수는 똑같은데 tp.id 를 쓰는 것과 p.id를 쓸 때 해석 차이가 무엇인지, 연습 문제가 아닌 실무에서 똑같은 상황일 때 p.id를 사용하면 어떤 문제가 발생하는지, 연습 문제처럼 COUNT로 집계 할 때 보통 어떤 테이블의 id를 COUNT 하는 것이 보편적인지 궁금합니다. SELECT kor_name, COUNT(tp.id) AS pokemon_cnt FROM( SELECT id, trainer_id, pokemon_id, status FROM basic.trainer_pokemon WHERE status IN("Active","Training") ) AS tp LEFT JOIN basic.pokemon AS p ON tp.pokemon_id = p.id GROUP BY kor_name ORDER BY 2 DESC
안녕하세요. 이전 질문에 대한 답변 감사합니다. type1을 기준으로 해서 4번 문제를 풀었는데요. 저는 trainer 테이블을 기준으로는 achivement_level = "Master"라는 조건이 있고, trainer_pokemon 테이블에서는 status IN ("Active", "Training")이라는 조건이 있으니 먼저 두 테이블을 이렇게 가공한 후에 JOIN하면 좋지 않을까? 라는 생각으로 아래와 같이 쿼리를 작성했어요. SELECT p.type1, COUNT(tp.id) type_cnt FROM (SELECT * FROM basic.trainer WHERE achievement_level = "Master") t LEFT JOIN (SELECT * FROM `basic.trainer_pokemon` WHERE status IN ("Active", "Training")) tp ON t.id = tp.trainer_id LEFT JOIN `basic.pokemon` p ON tp.pokemon_id = p.id GROUP BY p.type1 ORDER BY type_cnt DESC LIMIT 1 그런데 풀이에서는 trainer_pokemon 테이블만 status 기준으로 가공한 후, 나머지 테이블을 JOIN하고 -> 마지막에 WHERE 조건으로 achivement_level = "Master" 를 걸어서 데이터를 추리는 것 같더라고요. 현재 데이터 기준으로는 일단 값이 같지만, 뭔가 이 선후관계에 따라서 무언가가 달라질 수도 있을 것 같은데 명확하게 알기가 어려워 질문 드립니다! 확인 부탁 드립니다 :)
안녕하세요, 이번 강의를 듣고 아주 간단한 질문을 남깁니다. Soft Delete + 이력 테이블 설계가 필요한 이유가 외래 키 제약 조건으로 인한 삭제 어려움 때문이라 이해했습니다. 일부 실무자들은 이러한 삭제 불편함으로 인해 물리적으로 외래 키 제약조건을 DB에 걸지 않는다는 말을 들은 적이 있는 것 같은데요, 만약 그렇게 제약이 없다면 단순히 Hard Delete + 이력 테이블 구조로 고정해도 괜찮은 걸까요?
안녕하세요. 5-6. JOIN 연습문제 4번을 풀 때, pokemon 테이블에 type1도 있고, type2도 있는데 문제에서는 특정 하나를 사용하라고 되어있지 않아서 고민을 많이 했는데요. (type1 + type2 된 컬럼이 존재하는 새 테이블을 만들 수 있나? 까지 생각이 나아갔습니다...) 풀이를 보니, type1만 사용된 것 같아서요! type1과 type2가 모두 존재하는 포켓몬도 있어서, 이런 경우에 대한 대응은 어떻게 되는지 궁금합니다. type1이면서 type2인 포켓몬의 type1+type2 타입을 구하기 (ex.Grass&Poison) type1과 type2를 합집합으로 생각했을 때, 그 중에서 가장 많은 포켓몬 타입을 구하기 type1만 있거나, type2만 있거나, type1/2 모두 있는 케이스를 고려하여 특정 유의미한 데이터를 구하기 등의 다양한 요구 케이스가 발생할 수 있을 것 같아서요! 확인 부탁 드립니다 :)
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 primary key 로 where 절에 넣고 select 를 하면 key 에 primary 가 찍혀 효율적인 조회가 가능하다고 알고있습니다! 그런데 수업 내용에서 EXPLAIN SELECT item_id, price, item_name FROM items WHERE price BETWEEN 50000 AND 100000; 해당 쿼리를 사용하면 extra 에 Using index condition 나와 인덱스를 사용해서 구했다 < 까지는 이해가 가는데 여기서 item_id 라는 primary key 가 존재하는데 이거로 db 접글을 재시도하면 어째서 랜덤i/0가 발생하는건지 궁금합니다.
자빅스 에이전트 EC2 만드는데서 ZABBIX-GRP 보안그룹을 그대로 사용하는데 자빅스 서버 8080에서는 10050으로 연결해 연결이 되지 않습니다. 잘못 말씀하신건지 혹은 제가 실수한건지 궁금합니다. 실제로 10051로 해서 기본 템플릿에서 안되다가 10050으로 해서 연결되어서요..
date_part의 결과에 대한 data type을 출력해 보니 "double precision"으로 나옵니다. 저는 date_part에서 추출한 part가 예를 들어 'month'라고 하면 그 값 자체가 date 유형으로 생각해서 to_char(date_part('month', hiredate), 'month')의 결과가 'january' 로 기대했는데, 오류가 나오더라구요.
안녕하세요 카일스쿨님! BigQuery 기초편부터 활용편까지 유익하게 수강 중인 학생입니다 🙂 BigQuery 활용편 18강 "연결된 시트에서 매개 변수 사용하기" 부분에서 질문이 있습니다! 스샷 왼쪽(강의창)에서 선택하신 데이터 범위가 오른쪽(제 구글 시트 창)의 어떤 셀에 해당하는지 제가 잘 이해하지 못해서, 혹시 알려주실 수 있을까요~? 기술적인 내용이라 여쭤보기 민망하고 죄송스럽지만 가장 정확하게 답을 얻을 수 있을 것 같아 질문드립니다! 추신__ 에어팟 맥스처럼 귀에 챠악 감기는 강의 항상 감사합니당
안녕하세요. 주문, 상품과 같은 비즈니스에 중요한 데이터를 전체 행 스냅샷 이력 테이블 로 관리 하는 상황일 때, 대상 테이블(주문, 상품 등)의 칼럼이 추가/삭제되는 상황에 이력 테이블에 어떻게 반영해야할지 질문 드리고 싶습니다. - 추가: 신규 기능으로 인해 새로운 칼럼 추가 - 삭제: 기획 변경으로 오랜 기간 미사용 칼럼으로 낭비되어 삭제로 결정된 경우 등
안녕하세요 영한님. 강의 정말 잘 듣고 있습니다. common_code_detail 은 pk로 natural key(group_code, code) 를 사용하는 것이 정형화되어 있다고 하신 부분을 이해했습니다. 서비스를 운영하다 보면 code의 값을 수정할 경우가 생길 가능성이 있을 거 같은데요. 예를 들면, 다음과 같은 요구사항이 있을 거 같습니다. group_code가 ORDER_STATUS 인 code에 대한 변경 요청. SHIPPING 을 두가지 상태로 확장(SHIPPING_START, SHIPPING_COMPLETED) 변경 전의 SHIPPING은 SHIPPING_COMPLETED로 취급한다. 설계 1편의 "pk는 immutable해야한다" 라는 3번째 규칙이 있었는데요. 공통 코드 테이블의 경우에는 3번째 규칙을 유연하게 적용해야하나? 하는 생각이 들었습니다. 공통 테이블은 natural key를 사용하니 어느정도 허용을 한다고 보면 될까요? 아니면, 기존 키는 삭제하지 않은 채로 그대로 두고 새로 만들어서 규칙을 지키는 방향으로 하시는지 궁금하네요. 실무에서 이런 케이스들은 어떻게 다루시는지 궁금합니다. 감사합니다.
이번 강의의 수업자료 pdf 보니, 제목 클릭 시 링크위치가 각 챕터가 아닌, 마지막 페이지 정리 내 제목들로 이동합니다. 9. 논리적 모델링 - 실습.pdf 파일 제외하곤 모든 파일의 목차들이 다 마지막 정리로 이동하더라고요. 그동안 영한님 강의들 자료에는 각 챕터로 쉽게 이동 하기 좋았거든요. 이부분이 개선 가능할까요? 이 상태여도 학습은 가능한데, 건의드립니다. 감사합니다.
-- Weekly 리텐션 -- 핵심 : event_date => event_week으로 변경하면 됨 -- 2024-06-30(일) => 2024년 26주차. 2024-06-24(월)도 같은 26주차 -- 데이터를 전처리(가공)하기 위해서 WEEK 함수를 사용할 수도 있고, DATE_TRUNC(일자, 자를 기준) -- DATE_TRUNC : 2024-06-30 => 2024-06-24 -- WEEK : 26. 2024년 26주차! 주차 별 date를 직관적으로 알기 어렵다고 생각하는 편(개인 생각) -- (깨알 지식) WEEK vs ISO_WEEK -- 주 번호를 계산할 때 사용할 수 있는 함수 -- WEEK : 일요일이 주의 첫 날로 간주. 1월 1일이 속한 주가 1주차 -- ISO_WEEK : 월요일이 주의 첫 날로 간주. ISO 8601 국제 표준에 따라 정의. 목요일이 속한 주를 기준으로 주 번호를 지정 -- 목요일이 속하면 그 주의 4일 이상이 포함되기 때문 -- 연도의 첫 목요일이 있는 주부터 1주차 -- 2022년 1월 1일(토요일) WEEK : 2022년 1주차. ISO_WEEK 2021년 52주차. -- 첫 목요일은 2022-01-06. 2022-01-03~2022-01-09가 2022년 1주차 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-11-03" ), first_week_and_diff AS ( SELECT *, -- DATE_DIFF(event_date, first_date, DAY) AS diff_of_day DATE_DIFF(event_week, first_week, WEEK) AS diff_of_week FROM ( SELECT # 일자별로 중복 제거 DISTINCT user_pseudo_id, -- DATE_TRUNC 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 ) ), user_counts AS ( SELECT diff_of_week, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM first_week_and_diff GROUP BY diff_of_week ) SELECT *, ROUND(SAFE_DIVIDE(user_cnt, first_week_user_cnt), 2) AS retention_rate FROM ( SELECT diff_of_week, user_cnt, FIRST_VALUE(user_cnt) OVER(ORDER BY diff_of_week ASC) AS first_week_user_cnt FROM user_counts ) -- SELECT -- diff_of_week, -- COUNT(DISTINCT user_pseudo_id) AS user_cnt -- FROM first_week_and_diff -- GROUP BY diff_of_week -- ORDER BY diff_of_week # Monthly 리텐션 쿼리 작성해보기! 지금 코드가 각 diff_week마다 남은 유저들을 전체 유저로 나눠서 아 몇주차쯤 되면 얼마나 남아있는지를 계산한 거 같은데 생각해보니까 예를들어 지금 기간이 11월 3일까진데 한 10월 중순에 들어온 유저 같은 경우엔 diff_week가 한 3 이상인 부분부턴 아예 데이터가 없는거 아닌가요? 데이터가 11월 3일까지 밖에 없으니까요 분모로 사용하는 diff_week=0인 지점에서의 값은 그런 경우들까지 전부 포함된거고 그걸 그대로 모든 retention week마다 분모로 사용하면 위 예시 같은 경우 10월 중순 user들은 한 3주차쯤엔 전부 이탈하는 것 처럼 집계되는거 아닌가요? 그 경우 diff_week가 커질수록 실제 리텐션 보다 과소평가 되는게 아닌가 하는 의문점이 들어 문의 남깁니다
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 "2023-08-03" ), 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 ) ), user_counts AS ( SELECT first_week, weeks_after_first_week, COUNT(DISTINCT user_pseudo_id) AS active_users FROM first_week_and_diff GROUP BY first_week, weeks_after_first_week ) SELECT *, ROUND(SAFE_DIVIDE(active_users, cohort_users), 2) AS retention_rate FROM ( SELECT first_week, weeks_after_first_week, active_users, FIRST_VALUE(active_users) OVER(PARTITION BY first_week ORDER BY weeks_after_first_week ASC) AS cohort_users FROM user_counts ) ORDER BY first_week, weeks_after_first_week 수업때 사용했던 코드인데 제가 처음엔 지금 하고 있는 코호트 분석은 first_week(가입주) 마다 각자 시간이 흐르면서(기준은 week) 리텐션이 어떻게 바뀌는지를 보는 것 이라고 이해했었습니다 그래서 예를들어 첫 달 부터 확 떨어지면 이거 온보딩에 문제가 있는거 아닌가? 라는 문제정의를 하는 식의 생각을 할 수있다... 라고 이해하고 있었는데 다시 보니까 지금처럼 base에 날짜 조건을 필터링 하고 시작하면 min(event_date)를 걸어도 그게 실제 첫 가입일이 아닐 수 있는거 아닌가요? 예를들어 필터링 조건 이전인 2022년 7월에 가입을 한 사람이 2022년 10월에 다시 돌아왔다고 치면 이 경우 2022년 10월 가입 user로 집계되는거지 않나요? 그럼 본래 보려던 거랑 결이 달라지는게 아닌가 싶어서요