안녕하세요 카일스쿨님:) 좋은 강의 너무 잘 듣고 있습니다. 실습 하나 하나 하면서 여기까지 왔는데요. join 예제를 풀어보면서 궁금한 점이 생겨서요. inner join을 사용하면 좀 더 타이트하게 제약을 둘 수 있고, 테이블 크기 자체도 줄일 수 있을 거 같다는 생각이 들었습니다. 결과도 동일하게 확인했습니다. 예를 들어 join 3번 문제의 경우 trainer_pokemon 테이블에 inner join으로 trainer 테이블을 붙이면 결국 포켓몬을 잡아본 trainer로 테이블이 좁혀진다고 생각했고, 다른 경우의 수 생각할 필요 없이 location과 hometown만 비교해 결과를 얻었습니다. 이때 left join을 사용하시는 이유와, 그 장점에 대해 알 수 있을까요? 감사합니다!
안녕하세요 저희는 기존에 react + node를 사용해서 개발을 하고 있었는데요 python으로 변경하려는 상황입니다. 강의를 보면서 jinja라는 것을 알게 되었는데요. 찾아보니까 react를 사용하면 jinja를 사용하지 않는다고 하더라구요 react를 사용하는게 맞을까요 아니면 jinja를 사용하는게 맞을까요 보통 어떻게 많이 사용하나요?
Part 1 강의 듣고 따라오는 중인데 Part 2 강의도입부에 Dbeaver 설치랑 docker관련부분은 비전공자가 보기에 무슨 얘기를 하시는지를 모르겠어요... MS SQL 설치방법 에서 Dbeaver에 SQL 연결시에 "앞서 설정하셨던 패스워드를 입력합니다" 라고 하시는데 무슨 패스워드를 말씀하시는 걸까요? MyStrong@Passw0rd 를 입력하긴 했는데 test 커넥션 단계에서 "호스트 localhost, 포트 1433에 대한 TCP/IP 연결에 실패했습니다. 오류: "Connection refused: getsockopt. 연결 속성을 확인하세요. SQL Server의 인스턴스가 호스트에서 실행되고 있고 포트에서 TCP/IP 연결을 허용하고 있는지 확인하세요. 또한 방화벽에서 포트로의 TCP 연결을 차단하지 않는지 확인하세요." 라는 오류가 뜨면서 진행이 안됩니다.
안녕하세요 카일스쿨님! PM 강의부터 빅쿼리 SQL까지 너무 좋은 강의 덕분에 잘 공부하고 있습니다. 해당 내용을 블로그에 정리하고 싶은데요. 장표를 활용해도 될지 궁금합니다. 상업적인 광고는 달려 있지 않으며, 정리 용도로 제 생각을 덧붙여 정리 예정입니다. 저작권 관련 예민한 부분이라 미리 여쭤보며, 혹 불가능 하더라도 충분히 이해되는 부분입니다. 감사합니다!!
안녕하세요 카일님 강의 마지막에 주신 연습문제 해보았습니다. PIVOT에 어떤 연산자를 사용할 것인가? MAX로 할 경우 -> 별도의 연산된 결과값이 있는 base`가 필요할 것 같음. 이 경우 강의 중 작성된 cnt를 참조하여 작성할 수 있을 것 같으나 3중 쿼리라는게 마음에 걸림. SUM으로 할 경우 -> 강의 중 작성한 base 만으로 충분할 것 같음. 2중 쿼리로 충분해보임. 따라서 B안으로 작성해보았습니다. WITH base AS ( SELECT event_date, event_timestamp, event_name, user_id, user_pseudo_id, platform, -- event_param, MAX(IF(event_param.key = 'firebase_screen',event_param.value.string_value, NULL)) AS firebase_screen, -- MAX(IF(event_param.key = 'food_id',event_param.value.int_value, NULL)) AS food_id, MAX(IF(event_param.key = 'session_id',event_param.value.string_value, NULL)) AS session_id, FROM advanced.app_logs CROSS JOIN UNNEST(event_params) AS event_param WHERE -- event_date = '2022-08-01' -> 적은 데이터로 쿼리를 작성하기 위해 입력한 임시 조건 event_date BETWEEN '2022-08-01' AND '2022-08-18' GROUP BY ALL -- LIMIT 100 -> 기초 구문 작성 완료 시 삭제 필요! ), filter_event_and_concat_event_and_screen AS ( -- name, screen concatate (필요한 이벤트만 WHERE 조건 걸어 사용) SELECT * EXCEPT(event_name,firebase_screen, event_timestamp), CONCAT(event_name, '-', firebase_screen) AS event_name_with_screen, DATETIME(TIMESTAMP_MICROS(event_timestamp), 'Asia/Seoul') AS event_datetime FROM base WHERE event_name IN('screen_view', 'click_payment') ) # PIVOT 연습문제 SELECT event_date, SUM(IF(event_name_with_screen = 'screen_view-welcome',1,0)) AS `screen_view-welcome`, SUM(IF(event_name_with_screen = 'screen_view-home',1,0)) AS `screen_view-home`, SUM(IF(event_name_with_screen = 'screen_view-food_category',1,0)) AS `screen_view-food_category`, SUM(IF(event_name_with_screen = 'screen_view-restaurant',1,0)) AS `screen_view-restaurant`, SUM(IF(event_name_with_screen = 'screen_view-cart',1,0)) AS `screen_view-cart`, SUM(IF(event_name_with_screen = 'click_payment=cart',1,0)) AS `click_payment-cart`, FROM filter_event_and_concat_event_and_screen GROUP BY ALL ORDER BY event_date ASC
DELETE A1 FROM Person A1 INNER JOIN Person A2 ON A1.email = A2.email WHERE A1.id > A2.id; 이너조인 연습 DELETE FROM Person --삭제 WHERE id IN ( SELECT id --외부 서브쿼리 FROM ( SELECT id, --내부 서브쿼리 ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) as id_rank FROM Person ) Number_Practice WHERE id_rank > 1 --외부조건 2순위 이상 ); 윈도우함수 Row_number 활용 PARTITION BY - 그룹 ORDER BY - 순위 (id) WITH CTE_practice AS ( SELECT id, ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) as id_rank FROM Person ) DELETE FROM Person WHERE id IN (SELECT id FROM CTE_practice WHERE id_rank > 1); CTE 이용 WITH CTE_NAME AS ( 내부서브쿼리 ) DELECT WHERE id IN ( 외부 서브 쿼리) 3가지를 연습해봤는데, 실무적으로는 어느 것을 더 지향하는지 (좋은코드? 클린코드?) 궁금해서 질문드립니다.
좋은 강의 너무 감사드립니다! JOIN 개념 배우다가 의문이 생겨 질문 남깁니다! 혹시 JOIN 연산 수행했을 때 합쳐진(JOIN 결과) 테이블은 통째로 지정할 순 없나요? 예를 들면 실습해주신 쿼리에서, JOIN을 했는데 다시 tp.* , t.* , p.* 처럼 일일이 호출할 거면 JOIN한 의미가 있나 해서요.. 😅 JOIN을 했으니까, tp.* 만 호출해도 전체 테이블이 다 나오면 편할 거 같은데, 그렇게 되지 않는 이유가 궁금합니다!
안녕하세요. Weekly retention을 구하고자 아래와 같이 쿼리를 작성했습니다. WITH base AS (SELECT DISTINCT user_id, event_name, DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul') AS event_datetime, DATE(DATETIME(TIMESTAMP_MICROS(event_timestamp),'Asia/Seoul')) AS event_date, user_pseudo_id FROM `advanced.app_logs` WHERE event_date BETWEEN "2022-08-01" AND "2022-11-03" ), first_week_and_diff AS ( SELECT *, DATE_DIFF(event_week, first_week, WEEK) AS diff_of_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_cnt 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_cnt ); 이렇게 쿼리 작성을 하니 오류가 발생했고 user_cnt AS ( SELECT diff_of_week, COUNT(DISTINCT user_pseudo_id) AS user_cnt FROM first_week_and_diff GROUP BY diff_of_week ) 이 부분에서 테이블 이름을 user_counts로 수정하니 제대로 동작함을 확인했습니다. 왜 이름 때문에 오류가 발생하는 것인지 궁금합니다.
안녕하세요 카일님 1-5 학습 중 PIVOT 예제용 TABLE을 만들어 보려고 하였습니다. 결론부터 말씀드리면 TABLE 생성에 성공하였어요. 다만 궁금한 것은 제가 겪은 오류에 대한 해석이 올바른 것인지 확인 받고 싶어서 질문 드립니다. 1-4 강에 있던 array_exercise 생성 구문을 참고하여 아래와 같은 구문으로 실행하였더니 생성되지 않았습니다. 가장 안쪽의 select 부터 실행하면서 찾아보니 최하단의 UNION ALL이 원인이었더라구요. UNION ALL 은 아래에도 추가 ROW를 입력해야 할 때, 한 행으로 밀어넣는 명령어이므로, 마지막 행 다음에는 넣지 말아야 한다. 넣을 경우 그 뒤에 추가적인 데이터의 입력을 요구하나, 데이터가 없으므로 실행이 되지 않는 것이다. 라고 이해했는데, 맞게 이해했을까요? CREATE OR REPLACE TABLE `advanced.grade` AS SELECT student, grades FROM ( SELECT 'A' AS student, ARRAY<STRUCT<subject STRING, score INT64>>[ STRUCT('수학', 80), STRUCT('영어', 90), STRUCT('과학', 85) ] AS grades UNION ALL SELECT 'B', ARRAY<STRUCT<subject STRING, score INT64>>[ STRUCT('수학', 75), STRUCT('영어', 95), STRUCT('과학', 80) ] UNION ALL )
안녕하세요 카일님! 좋은 강의 너무 감사드립니다 :) 조건문 연습문제를 혼자 풀고 카일님이 작성하신 쿼리와 비교해보았는데 저와는 다르게 서브쿼리 없이 작성하셨더라고요! 결과는 잘 나오지만 서브쿼리를 사용하면 효율성이 떨어지는 쿼리일까요? 현업에서는 어떤 쿼리를 선호할까요? ('Old' 로 분류되는 결과도 얻고 싶어서 기준 날짜를 바꿨습니다.)
카일스쿨님 좋은 강의 감사드립니다! EXTRACT함수 예시 쿼리를 실행하니까 위와 같이 오류가 나서 여쭤봅니다. gpt한테 물어보니 AS DATETIME을 쓰지 말라고 하던데, 문법 자체가 바뀐 걸까요? 또한, 예시 쿼리 만드실 때 date, year 뽑는 쿼리에는 AS DATETIME을 안 쓰셨는데, month, day, hour, minute에는 쓰셨던 이유도 궁금합니다!
안녕하세요. 강의 잘 보고 있습니다. 강사님 쿼리 관련 설명에서, 로그시간이라는 단어를 사용하시는데, 이 로그시간이라는 것에 의미를 좀 알수 있을까요? ex: 정확한 데이터 기준점(board_id =1, article_id=5)이 있기 때문에, 인덱스에서 로그 시간에 기존점을 찾을 수 있다.
안녕하세요 해당 데이터셋에는 퍼널의 순서가 있다보니 각단계별 전환율을 구할 수 있었는데요, 다른 데이터의 경우 퍼널의 순서가 없다면 어떻게 분석을 해야할까요? 예를들어 "로그인 > 장바구니 >구매" 순서가 아닌 "로그인 > 구매" 이렇게 장바구니와 구매를 선택할수 있는 허브역할을 할 수도 있다고 생각되는데요. 이부분에서 개인적으로 공부하는데 막히더군요
3번 질문에서 1년 동안 완전히 이용 가능한 listings를 찾기 위해서 SELECT COUNT(DISTINCT id) FROM openairbnb.listings AS l WHERE l.availability_365 = 365; 1년 이용가능한 날이 365일인 고유한 id를 추출하는 쿼리를 이용하면 왜 답이 다르게 나온건지 모르겠습니다.
4번 문제를 혼자 먼저 풀어볼 때, SELECT COUNT(DISTINCT l.id ) FROM openairbnb.listings AS l WHERE l.availability_365 = 0; 이렇게 풀어서 같은 답이 나왔는데 해답에서는 서브쿼리를 이용하는 이유가 뭔지, 차이점이 있는지 궁금합니다.