게시글
질문&답변
2024.05.15
WITH 구문
mini0529님 안녕하세요! WITH 문 부분을 학습하고 계시면서 궁금한 내용이 생기셨군요! 질문해주셔서 감사합니다. 우선 WITH문을 제가 알려드린 이유는 논리적인 사고를 하기 위해 쿼리를 분리해서 생각하는 것이 필요하다 생각했어요. 실무에서 쿼리를 작성하다보면 500~1000줄 넘는 쿼리를 작성하는 경우가 많은데, 그냥 작성할 경우에 쿼리 유지보수가 정말 힘들어요. 한 부분에서 수정하면 다른 부분에 자동으로 적용되도록 하면 좋은데 조건을 주기적으로 추가해줘야 한다면, 실수할 가능성이 커지겠지요. 그래서 공통적으로 참조하거나 반복적으로 써야 한다면 WITH 문에 정의해서 사용하는 것을 추천드리고 있어요. 그래서 가독성과 유지 보수를 위해 WITH 문을 사용하는 것을 습관을 들이시면 좋겠다는 생각에 강의에 추가했어요. BigQuery에선 WITH문(CTE)이 쿼리에 영향을 미칠 수도 있지만, 공식적인 입장에선 가독성을 위해 사용한다고 말하고 있습니다. 공식 문서 : https://cloud.google.com/bigquery/docs/best-practices-performance-compute Note: WITH clauses with common table expressions (CTEs) are used for query readability, not performance. There is no guarantee that adding a WITH clause causes BigQuery to materialize temporary intermediate tables and reuse the temporary result for multiple references. The WITH clause might be evaluated multiple times within a query, depending on query optimizer decisions. 해석 : WITH 절과 공통 테이블 식(CTEs)은 쿼리의 가독성을 위해 사용되며, 성능 향상을 위한 것이 아닙니다. WITH 절을 추가한다고 해서 BigQuery가 임시 중간 테이블을 구체화하고 여러 번 참조할 때 임시 결과를 재사용한다는 보장은 없습니다. WITH 절은 쿼리 옵티마이저의 결정에 따라 쿼리 내에서 여러 번 평가될 수 있습니다. 참고로 위 이야기는 BigQuery 기준이고 다른 SQL 엔진에서는 다를 수도 있어요. 엔진마다 구체적인 구현 방식의 차이가 있기 때문에, 다른 SQL 엔진에선 다를 수 있어요. 실무적인 레벨에서 공유드리면 저는 꽤 긴 쿼리를 작성했지만, WITH 문 때문에 성능 하락을 경험한 적은 딱히 기억나진 않네요. 다만 쿼리가 500~1000줄 이상이 되면서 재사용이 많다면 별도의 물리적인 테이블(테이블을 하나로 저장)로 저장했기에 이런 것 같아요. 학습하는 입장에선 가독성을 챙기면서 쿼리를 작성해보자!라고 생각해보시고, 짧은 쿼리라고 하면 WITH 문을 꼭 굳이 안써도 된다 정도로 생각하시면 좋을 것 같네요. 저도 한번만 사용된다고 하면 그냥 서브 쿼리를 사용하는 경우도 있습니다. 반복적으로 사용될 것 같다 + 다른 사람이 봐야 한다! 하면 WITH 문을 작성하는 것을 추천드려요. 쿼리를 작성하는 것도 습관이라 처음부터 이런 습관을 가지는 것을 추천드려요. 쿼리를 그냥 작성하는 분들이 꽤 많기에 코딩 테스트나 쿼리 테스트에서 가독성을 고려해서 작성한다면, 구조적인 부분을 좋게 볼수도 있지 않을까 싶어요. 또 궁금한 내용이 있다면 언제든 말씀해주셔요. 감사합니다.
- 0
- 1
- 66
질문&답변
2024.05.08
JOIN 연습문제 5번 문제 관련해서 질문이 있습니다!
happycoding님 안녕하세요! 제가 강의에서 다룬 쿼리문은 다음과 같아요 SELECT generation, 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.trainer AS t ON tp.trainer_id = t.id LEFT JOIN basic.pokemon AS p ON tp.pokemon_id = p.id WHERE t.hometown = "Incheon" GROUP BY generation 여길 보면 "trainer_pokemon"에서 id, train_id, pokemon_id, status를 가져오는(쿼리 상에서 5번째 줄부터 12번째 줄) 부분에서 status에 Active, Training을 걸어줬답니다. 해피코딩님은 바깥에서 하신거고 저는 서브 쿼리에서 실행한거죠. 지금의 쿼리가 결과론적으론 같을 수 있는데 저는 서브쿼리로 데이터를 줄인 후에 처리하고 싶어서 미리 서브쿼리에서 데이터를 줄였다고 보시면 됩니다 우연히 인천에 있는 트레이너들의 status가 다 Active, Training 이어서 이렇게 된 것인지에 대한 것은 실제 쿼리에서 확인해보시면 됩니다. 어떻게 쿼리를 작서해야 할까요? 데이터 검증 파트를 보시고 오셔도 괜찮고, 한번 작성해보셔요. 제가 바로 답을 드리면 해피코딩님이 그렇구나~라고 하실 수도 있어서 질문을 먼저 해봅니다 인천에 있는 트레이너들의 status가 Active, Training만 있는지 혹은 다른 Value도 있는지 확인하기 위해선 어떻게 쿼리를 작성해야 할까요?
- 0
- 2
- 63
질문&답변
2024.05.07
5-6 의 Join 문제 2 해설이 일부 이해가 되지 않습니다
안녕하세요! 해당 문제의 답을 추상화하면 다음과 같습니다 SELECT p.type1, COUNT(tp.id) AS pokemon_cnt FROM Table_a(서브쿼리) LEFT JOIN Table_b ON Table_a.pokemon_id = Table_b.id WHERE type1 = "Grass" GROUP BY type1 GROUP BY 이 들어가야 하므로 type1을 명시해야 type1에 대해 GROUP BY를 해서, pokemon_cnt가 나온답니다. 왜 pokemon_cnt가 되어야 한다고 생각하시나요?(이 이유를 말씀해주시면 더 잘 설명드릴 수 있을 것 같아요. pokemon_cnt를 넣으시면 실행이 안될거에요) COUNT 같은 집계 함수는 GROUP BY에 들어가지 않습니다. SELECT를 하면서 type1을 사용해서 그룹화를 해야 하지요!
- 0
- 1
- 64
질문&답변
2024.05.02
4-8. 지표 정의 연습 문제 풀이 답변 올려볼게요!
wjdgml님 안녕하세요! 문제 잘 풀어주셨네요! 전반적으로 정의하는 습관을 들일 수 있게 하신 것 같아 잘 푸셨네요. 하나씩 의견 드리면 1번 기능이 잘 동작하려면? 댓글 또는 좋아요 같이 사람들이 상호작용을 하는지 ~ 사람들이 어떤 배너에 더 관심이 가는지 이 부분에 대해서는 추가적인 내용을 생각해봐도 좋을 것 같아요. "관심을 가질만한 배너에 해당하는지" 이런 질문의 경우 관심을 가지다를 정의해야 하고, 그거에 따라 지표가 나오겠지요. 사람들과 "상호작용"을 한다도 정의가 필요하고, 각각이 어떤 의미인지 생각해보는게 필요합니다. 지금 작성한 부분에서 한번 더 들어가보면 좋겠네요 노출 수에서 노출은 어떻게 구성되는지 아시나요? 이 부분을 추가적으로 공부해봐도 좋을 것 같아요. 노출 이벤트의 경우 자동으로 이동하는 배너가 있을 수 있고, 사용자가 직접 넘기는 배너가 있을 수 있고, 두개가 혼합된 경우도 있어요. 카카오톡 광고 등을 보시면 알 수 있을거에요 또한 노출이라는 것이 가로로 나오는 것은 좀 더 쉬운데, 당근마켓 같이 스크롤을 내리다가 노출이 되는 것은 어떤 시점에 노출을 해야할까요? 현업에서 자주 고민하는 주제입니다. 시작점에 노출을 하냐, 끝에 노출을 하느냐 더 나아가서 데이터 로그 설계 부분과 같이 생각하면 이게 왜 중요한지 이해할 수 있을거에요(정의에 따라 언제 데이터를 기록할지가 달라짐) 각 영역에서 어떤 지표가 제일 Focus 해야 하는 지표인지도 작성해보면 좋을 것 같네요 왜 이 지표를 선택해야 하는지?도 생각해보면 좋을 것 같습니다 2번 검색 만족도 지표 검색 이탈률을 검색 중단한 사용자 수라고 해주셨는데, 중단의 정의는 무엇인가요? 검색을 하고 결과창에서 특정 버튼을 통해 결제창으로 진입하고 있다면 이것은 중단일까요? 아닐까요? 중단, 이탈의 정의를 구체적으로 잡으면 꽤 까다롭습니다. 중단, 이탈에 대한 정의를 자세히 해보셔요 지표만 작성하는 것이 아니라 어떻게 해석할지, 왜 이 지표를 선택했는지를 같이 작성하는 것을 추천해요 3번. 검색 필터 활성화 지표 필터 내 체류 시간이 길지 않는가에서 체류 시간은 어떻게 계산할 수 있을까요? 만약 검색을 하다가 잠시 백그라운드로 들어간 후, 10초 뒤에 다시 앱으로 진입했다면 이것은 어떻게 데이터를 추출해야 할까요? 백그라운드를 제외하면 된다!라고 생각할 수 있는데 이것을 SQL 쿼리나 데이터 처리를 어떻게 해야할지 고민해보면 좋답니다 필터를 자주 바꿨다는 것은 원하는 제품이 없다일 수도 있지만, 고민을 계속 하고 있다고 볼 수도 있습니다. 두 주장을 뒷받침하기 위해 어떤 데이터를 찾아보며 근거를 제시하시겠어요?(어떤 데이터가 어떤 결과가 나온다면 이 주장이 맞을 수 있다 등의 문장을 정리해보면 될 것 같아요) 4번. 배달 서비스의 중요한 지표 배달 산업 관점으로 생각해보길 바라는 마음에 낸 문제였어요. 지표의 하이라키 잘 표현해주셨는데, 배달 서비스만 나타낼 수 있는 지표로 생각해보면 어떤 것을 뽑으시겠어요? 5번. 추천 알고리즘 성능 지표 말씀해주신 전환율, 클릭율도 성능 지표로 가능하지만 이런 알고리즘은 정해진 지표들이 존재합니다 https://sungkee-book.tistory.com/11 Precision, Recall 등도 확인해보시고 알고리즘 자체의 성능을 확인하는 것은 다양한 종류가 있구나, 매번 검색을 해보는 것을 추천드려요 6번. 자주 사용하는 서비스 잘 생각해주셨네요. 4번처럼 지표의 위계로 표현해보면 어떨까요? 반납과 예약을 기준으로 보신 포인트도 좋네요. 다만 반납이 1달 뒤에 진행된다고 하면 데이터가 shift가 될텐데 이런 경우엔 어떻게 해야할까요? 7번. 퍼널 개선 프로젝트 온보딩을 강제로 해야할까요? 선택으로 해야할까요? 이 기능 여부에 따라 지표 해석이 달라질 수도 있고, 평균적인 지표가 달라질 것 같네요(강제라고 하면 해당 지표는 거의 의미가 없어질 수 있겠지요. 고객이 선택할 수 있는 것이 없으니) 저 지표 하나로 확인할 수 있을까요? 데이터를 볼 때는 어떻게 해야할까요? AB Test 파트를 보시고 이 문제를 다시 보시는 것도 추천드려요
- 0
- 2
- 102
질문&답변
2024.04.29
4-5 연습문제 4번
안녕하세요! 4-5 연습문제 4번에서 서브쿼리에 *을 꼭 써야하는 이유는 서브쿼리 바깥에 있는 FROM 절 입장에선 서브쿼리가 일종의 테이블처럼 인식합니다. SELECT day_of_week, COUNT(DISTINCT id) AS battle_cnt FROM ( SELECT *, EXTRACT(DAYOFWEEK FROM battle_date) AS day_of_week FROM `basic.battle` ) GROUP BY day_of_week ORDER BY day_of_week 위 쿼리에 서브 쿼리인 SELECT *, EXTRACT(DAYOFWEEK FROM battle_date) AS day_of_week FROM `basic.battle` 위 쿼리를 실행해보면 다음과 같은 결과가 나타납니다 (사진) 위에 결과에서 아래 쿼리를 실행하는 것으로 볼 수 있습니다 SELECT day_of_week, COUNT(DISTINCT id) AS battle_cnt FROM 위 결과 테이블 GROUP BY day_of_week ORDER BY day_of_week 만약 서브 쿼리에서 *을 제외했으면 아래와 같은 결과가 나타납니다 SELECT EXTRACT(DAYOFWEEK FROM battle_date) AS day_of_week FROM `basic.battle` (사진) 즉, day_of_week 밖에 없는 데이터인거죠 그래서 아래 쿼리를 실행할 때, id가 없기 때문에 Unrecognized name(데이터에 해당 컬럼이 없다) 오류가 발생하는 것입니다 SELECT day_of_week, COUNT(DISTINCT id) AS battle_cnt FROM 위 결과 테이블 GROUP BY day_of_week ORDER BY day_of_week 그렇다면 여기서 COUNT(DISTINCT *)도 가능한가? DISTINCT를 할 때는 구체적인 컬럼을 명시해야 하기 때문에 실행이 안됩니다 그럼 COUNT(*)도 가능한가? 실행은 되지만 단순히 Row 수만 COUNT하게 됩니다. 지금 데이터에선 답이 같을 수 있지만, id가 중복으로 존재하는 테이블에서는 COUNT(*)은 의도와 다른 값이 나타날 수 있습니다. 그래서 id를 DISTINCT해서 고유값만 COUNT한 것이에요 정리하면, 서브 쿼리에 있는 컬럼이 있어야 바깥에서 불러올 수 있습니다. 일종의 테이블이라고 생각하시면 이해가 쉬울 것 같네요
- 0
- 1
- 70
질문&답변
2024.04.29
battle 파일 표시할 데이터가 없습니다 문제
유정님 안녕하세요. 최근에 비슷한 질문이 있었는데, 아래 글에 해결 방식을 작성해두었어요. 확인해주시겠어요? 빅쿼리 내부의 오류로 파티션을 설정할 때 데이터가 사라지는 오류 같아요. 파티션 설정을 하지 않고 테이블을 생성했을 때 데이터가 보이면 아래의 이슈와 동일한 이슈일 것 같아요. https://www.inflearn.com/questions/1250442/battle-%ED%85%8C%EC%9D%B4%EB%B8%94-%ED%98%95%EC%84%B1%ED%95%A0-%EB%95%8C-%EC%A0%9C%EA%B0%80-%EC%96%B4%EB%96%A4-%EC%8B%A4%EC%88%98%EB%A5%BC-%ED%96%88%EC%9D%84%EA%B9%8C%EC%9A%94
- 0
- 1
- 70
질문&답변
2024.04.29
sql 실행순서와 서브쿼리 사용이유
안녕하세요. 우선 쿼리 실행 순서는 FROM - WHERE - GROUP BY - HAVING - SELECT 순서로 진행됩니다. 이런 경우라면 SELECT에서 Alias를 걸었던 컬럼을 GROUP BY에서 사용하지 못하는 것이 일반적입니다. 그러나 BigQuery에선 이런 경우에 SELECT의 Alias를 인식해서 GROUP BY에도 사용할 수 있도록 해주고 있어요. 과거엔 BigQuery도 SELECT Alias가 안되다가 기능이 생겼어요. 그래서 빅쿼리에선 해당 경우에도 실행이 됩니다만 실행 순서는 GROUP BY가 더 빠르다고 알고 계시면 좋을 것 같아요 아래 쿼리는 목적에 따라 다를 것 같아요. 1회성으로 new_type1이랑 집계만 하면 후자 쿼리가 더 좋을 수 있는데, 이 쿼리 결과를 가지고 다른 곳에서 많이 사용한다고 하면 전자가 더 좋을 수도 있지요. 사용 목적에 따라 다른 판단을 할 것 같네요. 서브 쿼리는 다양한 목적으로 사용하는데, 한번 더 데이터를 전처리해야 하는 경우가 있습니다. 한번 더 데이터를 가공하고 필터링할 때 사용할 수 있습니다. 서브 쿼리를 사용하냐 안하냐는 상황에 따라 다릅니다. 지금 수강하시는 강의는 쿼리가 다 짧고 JOIN이 없어서 서브 쿼리의 필요성을 느끼기 어려울 수 있으나 JOIN을 배우고 현업으로 갈수록 복잡한 구조에서 데이터 필터링을 할 때 서브 쿼리를 사용하기도 합니다(그 외에 가독성 목적도 있고 목적이 다양해요)
- 0
- 1
- 81
질문&답변
2024.04.27
코드 에디터가 이상한데, 어떤 설정을 건드려야할지 모르겠어요.
시주님 안녕하세요! 앗 이런 경우엔 아마 빅쿼리의 오류인 것 같아요. 시간이 지나고 다시 해보시거나 다른 웹브라우저에서 하셔도 그럴까요? 가끔 이런 경우가 있는데 시간이 지나면 버그가 고쳐졌던 것 같아요!
- 0
- 1
- 71
질문&답변
2024.04.27
4-5. 시간 데이터 연습 문제 2번 문제 관련
안녕하세요. 해당 부분은 해석에 따라 애매할 수도 있겠네요. 18시 사이라고 했는데 18시 59분까지 포함한 의미로 쿼리를 작성했네요. 말씀하신 경우로 생각해보면 해당 강의에서
- 0
- 1
- 59
질문&답변
2024.04.26
battle 테이블 형성할 때 제가 어떤 실수를 했을까요?
240426 원격으로 봤는데, PARTITION BY를 할 때 이슈가 있었어요 DML 쿼리를 사용할 때도 PARTITION BY가 없을 땐 잘 저장되다가 넣는 순간 데이터가 사라집니다 이는 BigQuery 자체 오류 같아요. 제 계정은 되는데 wjdgml님 계정에서만 발생하네요 저도 빅쿼리쪽에 한번 문의 넣어볼게요. 이런 이슈가 보통 몇일 뒤에 하면 해결되기도 합니다 wjdgml님에게는 제가 일단 실습하실 수 있도록 설정해드렸어요 1) 데이터를 생성할 때 자동 탐지 설정하고 생성(파티션을 설정하면 데이터가 없어지므로) : test 테이블 2) 생성된 데이터를 의도된 형태로 다시 쿼리 SELECT id, player1_id, player2_id, winner_id, battle_date, DATETIME(battle_datetime) AS battle_datetime, TIMESTAMP(DATETIME(battle_datetime)) AS battle_timestamp FROM `basic.test` 3) 쿼리 실행 후, 쿼리 저장 - BigQuery 테이블 클릭한 후, battle_temp라고 저장 (사진) 4) 파티션을 설정하기 위해 아래 DML 쿼리 실행 => wjdgml님은 PARTITION BY를 사용할 경우 데이터가 모두 사라지는 현상이였어요 CREATE OR REPLACE TABLE `basic.battle` PARTITION BY DATE(battle_datetime) AS SELECT id, player1_id, player2_id, winner_id, battle_date, battle_datetime, battle_timestamp FROM `basic.battle_temp` 파티션 설정이 강의에서 필수는 아니기에 일단 학습하시고 추후에 다시 해보는 것으로 이야기했습니다. 파티션을 설정해야 한다는 것을 알려드리기 위함이였어서 만약 다른 분들도 비슷한 이슈를 겪으시면 이렇게 저장하시고 쿼리 실습하셔도 충분히 이해가 될거에요.
- 1
- 3
- 115