inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

[과제] 퍼널 PIVOT 테이블 작성하기

해결됨

BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)

안녕하세요 카일님! 강의 너무 잘 듣고 있습니다! 온오프라인에서 SQL실무와 관련된 강의가 없어 많이 고민했는데 카일님 강의 덕분에 입문 강의 부터 정말 많이 배웠습니다 ㅜㅜ! 아래 일자별 퍼널을 PIVOT 해보는 쿼리를 짜봤는데 피드백 주시면 너무 감사하겠습니다! 더불어서 PIVOT을 할 때 제가 아래 주석처리한 것들도 디버깅 했을때는 동일하게 나왔는데 혹시나 실무단에서 어떻게 하는건 조심해야한다! 라는 부분이 있을지도 궁금합니다..! 항상 감사합니다 :) #일자별 퍼널 PIVOT WITH base AS ( SELECT event_date, event_timestamp, event_name, user_id, user_pseudo_id, platform, MAX(IF(param.key = "firebase_screen", param.value.string_value, NULL )) AS firebase_screen, -- MAX(IF(param.key = "food_id", param.value.int_value, NULL )) AS food_id, MAX(IF(param.key = "session_id", param.value.string_value, NULL )) AS session_id, -- param.key AS screen, -- param.value.string_value AS string_value, -- param.value.int_value AS int_value, FROM `advanced.app_logs` CROSS JOIN UNNEST(event_params) AS param WHERE -- event_date = "2022-08-01" #적은 데이터로 쿼리를 작성하기 위해 만들어둔 조건 event_date BETWEEN "2022-08-01" AND "2022-08-18" GROUP BY ALL ), filter_event_and_concat_event_and_screen AS ( SELECT * EXCEPT(event_name,firebase_screen), 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") ), event_by_user_cnt_by_date AS ( --event_name + screen (필요한 이벤트만 WHERE 조건에 걸어서 사용) --step_number + COUNT --step_number : CASE WHEN 사용해 숫자 지정 1~6 (welcome, home, food_category, restaurant, cart ) SELECT -- DISTINCT event_name_with_screen, #해당 열 Unique값 확인 가능 event_date, #일자별로 퍼널별 유저수 쿼리 event_name_with_screen, -- event_datetime, user_pseudo_id, CASE WHEN event_name_with_screen = "screen_view-welcome" THEN 1 WHEN event_name_with_screen = "screen_view-home" THEN 2 WHEN event_name_with_screen = "screen_view-food_category" THEN 3 WHEN event_name_with_screen = "screen_view-restaurarnt" THEN 4 WHEN event_name_with_screen = "screen_view-cart" THEN 5 WHEN event_name_with_screen = "click_payment-cart" THEN 6 ELSE NULL END AS step_number, # 퍼널 단계 표시 COUNT(DISTINCT user_pseudo_id) AS cnt FROM filter_event_and_concat_event_and_screen GROUP BY ALL --screen_view-restaurant/screen_view-food_detail/screen_view-search/screen_view-search_result 도 퍼널 정의에 어떻게 넣을지 생각해보고 단계에 넣어보기 > 고객이 어떤 흐름으로 움직이는지 확인해보기 HAVING step_number IS NOT NULL ORDER BY event_date ) SELECT event_date, SUM(IF(event_name_with_screen = 'screen_view-welcome', cnt, NULL)) AS screen_view_welcome, SUM(IF(event_name_with_screen = 'screen_view-home', cnt, NULL)) AS screen_view_home, SUM(IF(event_name_with_screen = 'screen_view-food_category', cnt, NULL )) AS screen_view_food_category, SUM(IF(event_name_with_screen = 'screen_view-restaurarnt', cnt, NULL)) AS screen_view_restaurarnt, SUM(IF(event_name_with_screen = 'screen_view-cart', cnt, NULL)) AS screen_view_cart, SUM(IF(event_name_with_screen = 'click_payment-cart', cnt, NULL)) AS click_payment_cart, -- MAX(IF(event_name_with_screen = 'screen_view-welcome', cnt, NULL)) AS screen_view_welcome, -- MAX(IF(event_name_with_screen = 'screen_view-home', cnt, NULL)) AS screen_view_home, -- MAX(IF(event_name_with_screen = 'screen_view-food_category', cnt, NULL )) AS screen_view_food_category, -- MAX(IF(event_name_with_screen = 'screen_view-restaurarnt', cnt, NULL)) AS screen_view_restaurarnt, -- MAX(IF(event_name_with_screen = 'screen_view-cart', cnt, NULL)) AS screen_view_cart, -- MAX(IF(event_name_with_screen = 'click_payment-cart', cnt, NULL)) AS click_payment_cart, -- MAX(CASE WHEN event_name_with_screen = 'screen_view-welcome' THEN cnt END) AS screen_view_welcome, -- MAX(CASE WHEN event_name_with_screen = 'screen_view-home' THEN cnt END) AS screen_view_home, -- MAX(CASE WHEN event_name_with_screen = 'screen_view-food_category'THEN cnt END) AS screen_view_food_category, -- MAX(CASE WHEN event_name_with_screen = 'screen_view-restaurarnt'THEN cnt END) AS screen_view_restaurarnt, -- MAX(CASE WHEN event_name_with_screen = 'screen_view-cart'THEN cnt END) AS screen_view_cart, -- MAX(CASE WHEN event_name_with_screen = 'click_payment-cart'THEN cnt END) AS click_payment_cart FROM event_by_user_cnt_by_date GROUP BY event_date ORDER BY event_date ;

  • sql
  • bigquery
jinnie8230 댓글 2 좋아요 0 조회수 99

setAvatarImage(null) 부분 질문

미해결

한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편

선생님, 안녕하세요. 강의 잘 듣고 있습니다 🙂 프로필 수정 기능구현하기 - 기능 강좌에서 useEffect(() => { if (profile && isOpen) { setNickname(profile.nickname); setBio(profile.bio); setAvatarImage(null); } }, [profile, isOpen]); setAvatarImage(null); setAvatarImage의 인수로 null 값으로 설정한 이유를 강의에서 말씀 주셨는데 설명을 들었는데도 아직 잘 이해가 안 돼서요 ㅠㅠ 해당 부분에 대해 좀 더 부연설명 해주실 수 있나요? 감사합니다. 새해 복 많이 받으세요!

  • react
  • typescript
  • react-query
  • supabase
  • zustand
산독기 댓글 2 좋아요 0 조회수 60

cursor ai 설치시 오류

미해결

클로드 코드 완벽 마스터: AI 개발 워크플로우 기초부터 실전까지

cursor ai 설치를 하면서 중간에 open cursor from terminal 이것을 설치 하는 부분에서 설치가 되지 않습니다. 그래서 그냥 패스 하고 설치를 했는데 어디에서 저걸 설치를 해야할까여? 저게 설치가 되지 않아서 인지 강의에서 보이는 오픈 파일 중에서 CLAUDE.md 파일이 보이지 않습니다.

  • react
  • next.js
  • cursor
  • tailwindcss
  • claude
heasolpapa1222 댓글 2 좋아요 0 조회수 329

useState 자동생성 하실때 누른 키보드가 궁금합니다.

미해결

타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게

안녕하세요. 누르신 키보드가 어떤것인지 질문 드립니다. useSta까지 입력하시고 자동생성된 useStateSnippet를 선택을 하셔서 const [first, setFirst] = useState 이게 자동으로 생성이 되는데 생성이 되자마자 어떤 키보드를 누르셨는지 [showNotification, setShowNotification]= useState(second) 로 변경이 되더라구요.. 어떤 것을 입력하셔서 변경이 됬는지 알 수 있을까요?

  • react
  • react-router
  • redux-toolkit
  • zustand
  • react.js
면류관받는날까지# 댓글 1 좋아요 0 조회수 64

queue에 값을 추가하는 메서드는 어떤 차이가 있나요?

해결됨

2026 코딩테스트 올인원 [JAVA]

학습 관련 질문을 남겨주세요. 구체적으로 적을수록 좋아요! 마크다운과 단축키를 활용하면 글을 더 편하게 작성할 수 있어요. 커뮤니티 질문 & 답변에 비슷한 내용이 있었는지 먼저 검색해보세요. 편하게 질문주세요:) 직접 답변 드리도록 하겠습니다~ Queue에 값을 추가하는 메서드는 enque offer 두 가지가 있다고 강의에서 말씀 주셨습니다. 둘 다 똑같이 값을 추가하는걸까요? 만약 맞다면, 어떤 차이점이 있는지 궁금합니다. (어떤 상황에서 사용되는지도 궁금해요.) +추가적으로, queue.poll() 이 dequeue다 라고 말씀 주셨는데, 둘도 어떤 차이가 있는지. 어떤 상황에서 사용하는지도 궁금합니다!

  • java
  • 코딩-테스트
  • 알고리즘
  • data-structure
겁많은 김앙리 댓글 1 좋아요 0 조회수 108

74 미션에서

미해결

클로드 코드 완벽 마스터: AI 개발 워크플로우 기초부터 실전까지

이전에.. claude-nextjs-starterkit, claude-code-mastery, claude-nextjs-starters 등등 여러개의 폴더를 생성 해서 next.js 를 설치 하고 진행 하는 영상이 있었는데요. 74 미션에서 위의 첨부한 그림은 claude-nextjs-starters 인데..목소리는 claude-nextjs-starterkit 을 다운 받으라고 하고..도대체 뭐가 맞는 건가요? 아니면..그냥 next.js 설치 해서 하면 되는건가요? 차라리..이게 더 편하겠는데..

  • react
  • next.js
  • cursor
  • tailwindcss
  • claude
민경언 댓글 2 좋아요 0 조회수 139

72 메타프롬프트 활욘 PRD 생성(+MVP) 에서 질문

미해결

클로드 코드 완벽 마스터: AI 개발 워크플로우 기초부터 실전까지

88. 서브에이전트 를 보니까..72 메타프롬프트 활욘 PRD 생성(+MVP) 에서 새롭게 시작 한다는 노션을 사용 하는 화면을 확인할 수 있었습니다. 그 이전에서는 화면을 볼 수 없어서..88 까지 확인을 했는데요. 궁금한게 72 영상을 보면 claude_nextjs_starters 라는 것을 복사 해서 새로운 폴더를 만들었는데요. claude_nextjs_starters 라는 것은 이전 챕터 MCP 에서만 하더라도 shadcnui 로 로그인 페이지 만들고 하던 것 아니었나요? 그런데 여기에 노션 작업을 추가 하는 건가요? CLAUDE.md 를 참고사항으로 적는 걸 보면 68,69 mcp server 영상 에서의 claude_nextjs_starters 는 아닌 것 같은데.. 도대체 감을 못잡겠네..

  • react
  • next.js
  • cursor
  • tailwindcss
  • claude
민경언 댓글 2 좋아요 0 조회수 172

72 메타프롬프트 활욘 PRD 생성(+MVP) 에서 질문

미해결

클로드 코드 완벽 마스터: AI 개발 워크플로우 기초부터 실전까지

88. 서브에이전트 를 보니까..72 메타프롬프트 활욘 PRD 생성(+MVP) 에서 새롭게 시작 한다는 노션을 사용 하는 화면을 확인할 수 있었습니다. 그 이전에서는 화면을 볼 수 없어서..88 까지 확인을 했는데요. 궁금한게 72 영상을 보면 claude_nextjs_starters 라는 것을 복사 해서 새로운 폴더를 만들었는데요. claude_nextjs_starters 라는 것은 이전 챕터 MCP 에서만 하더라도 shadcnui 로 로그인 페이지 만들고 하던 것 아니었나요? 그런데 여기에 노션 작업을 추가 하는 건가요? CLAUDE.md 를 참고사항으로 적는 걸 보면 68,69 mcp server 영상 에서의 claude_nextjs_starters 는 아닌 것 같은데.. 도대체 감을 못잡겠네..

  • react
  • next.js
  • cursor
  • tailwindcss
  • claude
민경언 댓글 1 좋아요 0 조회수 190

8장 마지막 강의 시 오류

미해결

코드로 배우는 React 19 with 스프링부트 API서버

org.springframework.security .authorization.AuthorizationDeniedException: Access Denied product 관련해서 axios를 jwtAxios로 변경 완료 후 리스트 진입을 시도하려하면 위와 같이 서버 오류와 응답코드로는 403이 나타나고 있습니다. 여기서 의문은... todo쪽은 정상조회되고 product쪽은 액세스토큰, 리프레시도 모두 정상인데 접근이 안되고 있습니다ㅜㅜ

  • react
  • typescript
  • spring-boot
  • jpa
  • jwt
feelsagood 댓글 4 좋아요 0 조회수 130

cursor & claude code

미해결

클로드 코드 완벽 마스터: AI 개발 워크플로우 기초부터 실전까지

여기서 엔터 누르면 될까요?

  • react
  • next.js
  • cursor
  • tailwindcss
  • claude
김현우 댓글 2 좋아요 0 조회수 243

@agent-prd-generator

미해결

클로드 코드 완벽 마스터: AI 개발 워크플로우 기초부터 실전까지

docs에 제공해 주신 prd-generator.md를 생성했고 Claude를 실행했을 때 @prd를 하면 아래와 같이 나오는데요, agent-prd-generator는 어디에 나오나요?

  • react
  • next.js
  • cursor
  • tailwindcss
  • claude
read.eun77 댓글 3 좋아요 0 조회수 265

Day 19 미션 안내 질문

해결됨

한입 챌린지 7기 - React.js

Day 19 미션 안내에서 '요구사항 2'의 State 생성 요구사항 중 action.type 이 INIT 인 경우에는 어떤 액션을 구현 하면 될까요?

  • javascript
  • react
  • node.js
  • react.js
Lucy 댓글 2 좋아요 0 조회수 90

구글이 이메일 변경을 허용하는 이유

미해결

김영한의 실전 데이터베이스 - 설계 1편, 현대적 데이터 모델링 완전 정복

이번에 설계 1편에서 자연 키와 대리 키 부분을 학습하면서, 최근 구글이 이메일 변경을 부분적으로 검토하고 있다는 뉴스가 떠올랐습니다. 예전에는 이메일 변경이 거의 불가능했던 이유가 이메일을 자연 키처럼 사용해왔기 때문이라고 이해해도 될까요? 그리고 지금에 와서는 어떤 구조적 변화나 트레이드오프를 통해 이메일 변경이 가능해졌는지도 궁금합니다.

  • sql
  • mysql
  • dbms/rdbms
  • 소프트웨어-설계
  • SQLD
댓글 1 좋아요 0 조회수 129

강의자료문의

해결됨

누구보다 빠르게 배우는 Springboot + React RestAPI 게시판 만들기

react ui 만들기 강의에서 헤더의파일같은거는 강의자료에 있다고 하셨는데 강의자료는 어디에 있나요?? 노션에도 없던데

  • react
  • java
  • kotlin
  • spring-boot
  • jpa
댓글 2 좋아요 1 조회수 90

도메인 모델 패턴 vs 트랜잭션 스크립트 패턴

미해결

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 주문 서비스에서 주문, 주문 취소 메서드 비즈니스 로직이 엔티티에 있는데 이렇게 엔티티가 비즈니스 로직을 가지는 도메인 모델 패턴과 서비스에서 비즈니스 로직을 처리하는 트랜잭션 스크립트 패턴 중에 실무에서는 보통 어떤 것을 사용하나요? 각각의 장단점이 있는지도 궁금합니다

  • java
  • spring
  • 웹앱
  • spring-boot
  • jpa
www 댓글 1 좋아요 0 조회수 117

props 질문

해결됨

한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편

TodoItem 에서 todo값을 props로 넘겨줄때 왜 {...todo} 로 사용하나요? {todo} 는 안되는건가요?

  • react
  • typescript
  • react-query
  • supabase
  • zustand
gmldnjs0402 댓글 2 좋아요 0 조회수 58

로그인시 401 Unauthorized 오류가 뜹니다

미해결

[리뉴얼] React로 NodeBird SNS 만들기

로그인시 401 Unauthorized 오류가 떠서 리덕스 액션을 봤더니 LOG_IN_FAILURE에 error 내용이 비어 있었습니다. routes/user.js const express = require("express"); const bcrypt = require("bcrypt"); const { User, Post } = require("../models"); const passport = require("passport"); const router = express.Router(); router.post("/login", (req, res, next) => { console.log("🧾 req.body:", req.body); passport.authenticate("local", (err, user, info) => { if (err) { console.error(err); return next(err); } if (info) { return res.status(401).send(info.reason); } return req.login(user, async (loginerr) => { if (loginerr) { console.error(loginerr); return next(loginerr); } const fullUserWithoutPassword = await User.findOne({ where: { id: user.id }, attributes: { exclude: ["password"], }, include: [ { model: Post, }, { model: User, as: "Followings", }, { model: User, as: "Followers", }, ], }); return res.status(200).json(fullUserWithoutPassword); }); })(req, res, next); }); router.post("/", async (req, res, next) => { try { const exUser = await User.findOne({ where: { email: req.body.email, }, }); if (exUser) { return res.status(403).send("이미 사용중인 아이디입니다."); } const hashedPassword = await bcrypt.hash(req.body.password, 12); await User.create({ email: req.body.email, nickname: req.body.nickname, password: hashedPassword, }); res.status(201).send("ok"); } catch (error) { console.error(error); next(error); } }); module.exports = router; 세션 쿠키가 잘 전달이 안된건가 싶어서 req.body를 서버 터미널로 찍었더니 req.body: undefined 로 나왔습니다. 로그인 폼에서 데이터를 잘못 넘겨준건가 해서 확인해봤더니 loginForm.js const onSubmitForm = useCallback(() => { console.log(email, password); dispatch(loginRequestAction({ email, password })); }, [email, password]); 데이터도 잘 넘겨준 것 같고 sagas/user.js function logInAPI(data) { return axios.post("/user/login", data); } function* logIn(action) { try { const result = yield call(logInAPI, action.data); yield put({ type: LOG_IN_SUCCESS, data: result.data, }); } catch (err) { console.error(err); yield put({ type: LOG_IN_FAILURE, error: err.response.data, }); } } 사가쪽도 문제가 없어보여서 프론트 쪽 문제는 아닌 것 같고 백엔드쪽 문제 같은데 도저히 어디서 문제가 생긴건지 모르겠습니다. app.js const express = require("express"); const cors = require("cors"); const session = require("express-session"); const cookieParser = require("cookie-parser"); const postRouter = require("./routes/post"); const userRouter = require("./routes/user"); const db = require("./models"); const passportConfig = require("./passport"); const passport = require("passport"); const dotenv = require("dotenv"); dotenv.config(); const app = express(); db.sequelize .sync() .then(() => { console.log("db 연결성공"); }) .catch(console.error); passportConfig(); app.use( cors({ origin: "*", credentials: false, }) ); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use( session({ saveUninitialized: false, resave: false, secret: process.env.COOKIE_SECRET, }) ); app.use(passport.initialize()); app.use(passport.session()); app.get("/", (req, res) => { res.send("hello express"); }); app.get("/api", (req, res) => { res.json([ { id: 1, content: "hello", }, { id: 2, content: "hello2", }, { id: 3, content: "hello3", }, ]); }); app.get("/api/posts", (req, res) => { res.json([ { id: 1, content: "hello", }, { id: 2, content: "hello2", }, { id: 3, content: "hello3", }, ]); }); app.use("/post", postRouter); app.use("/user", userRouter); app.listen(3065, () => { console.log("서버 실행 중!"); }); passport/local.js const passport = require("passport"); const { Strategy: LocalStrategy } = require("passport-local"); const { User } = require("../models"); const bcrypt = require("bcrypt"); module.exports = () => { passport.use( new LocalStrategy( { usernameField: "email", passwordField: "password", }, async (email, password, done) => { try { console.log("입력값:", email, password); const user = await User.findOne({ where: { email }, }); console.log("찾은 유저:", user && user.email); if (!user) { return done(null, false, { reason: "존재하지 않는 이메일입니다!" }); } const result = await bcrypt.compare(password, user.password); if (result) { return done(null, user); } return done(null, false, { reason: "비밀번호가 틀렸습니다." }); } catch (error) { console.log(error); return done(error); } } ) ); }; passport/index.js const passport = require("passport"); const local = require("./local"); const { User } = require("../models"); module.exports = () => { passport.serializeUser((user, done) => { done(null, user.id); }); passport.deserializeUser(async (id, done) => { try { const user = await User.findOne({ where: { id } }); done(null, user); } catch (error) { console.error(error); done(error); } }); local(); }; 백엔드 코드를 첨부하였습니다. 터미널에 나온 콘솔 내용입니다. local.js파일에서도 콘솔("입력값:","찾은 유저:" )을 찍었는데 터미널에 찍힌 콘솔은 req.body만 찍혔습니다..

  • react
  • redux
  • node.js
  • express
  • next.js
현석 댓글 1 좋아요 0 조회수 120

INSERT INTO 관련 질문

미해결

김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] insert into 할때 괄호로 열을 지정하지않고 생략한다면 table을 생성할때 작성한 열 순서대로만 넣어야하는건가요?? 강의에 열의 순서라는게 그걸 뜻하는게 궁금해요

  • sql
  • mysql
  • dbms/rdbms
  • SQLD
escho94 댓글 1 좋아요 0 조회수 121

수강기간 변경 요청

해결됨

[백문이불여일타] 데이터 분석을 위한 기초 SQL

안녕하세요. 앱으로 수강을 해서 수강 도중에 기간이 무제한으로 바뀐 줄 모르고 들었는데요. 12월 29일자로 만료가 되긴했는데 혹시 수강기한 변경이 가능하다면 변경해주시면 감사하겠습니다!

  • sql
  • mysql
  • 카카오공채-서비스
solsolala66 댓글 2 좋아요 0 조회수 129

인기 태그

인프런 TOP Writers

주간 인기글