๐Ÿ“SQL ๊ธฐ๋ณธ ๋‹ค์ง€๊ธฐ(Select, Group By)

Umji Youยท2021๋…„ 8์›” 16์ผ

MySQL

๋ชฉ๋ก ๋ณด๊ธฐ
1/3

๐Ÿ“8์ผ์ฐจ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‹ค์Šต

1. SQL(DDL,DML,DCL)

DDL(Data Definition Language) - ๋ฐ์ดํ„ฐ ์ •์˜์–ด

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ์–ธ์–ด์ด๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฆฌ๋ฅผ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œํ•˜๋Š” ๋“ฑ์˜ ๋ฐ์ดํ„ฐ์˜ ์ „์ฒด์˜ ๊ณจ๊ฒฉ์„ ๊ฒฐ์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ์–ธ์–ด์ด๋‹ค.

์ข…๋ฅ˜์—ญํ• 
CREATE๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํ…Œ์ด๋ธ”๋“ฑ์„ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
ALTERํ…Œ์ด๋ธ”์„ ์ˆ˜์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
DROP๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํ…Œ์ด๋ธ”์„ ์‚ญ์ œํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
TRUNCATEํ…Œ์ด๋ธ”์„ ์ดˆ๊ธฐํ™” ์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • SCHEMA, DOMAIN, TABLE, VIEW, INDEX๋ฅผ ์ •์˜ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ ๋˜๋Š” ์‚ญ์ œํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด์ž…๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๊ด€๋ฆฌ์ž๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„์ž๊ฐ€ ์‚ฌ์šฉํ•œ๋‹ค.

DML(Data Manipulation Language) - ๋ฐ์ดํ„ฐ ์กฐ์ž‘์–ด

์ •์˜๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ž…๋ ฅ๋œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๋“ฑ์˜ ์—ญํ• ์„ ํ•˜๋Š” ์–ธ์–ด๋ฅผ ๋งํ•œ๋‹ค.

์ข…๋ฅ˜์—ญํ• 
SELECT๋ฐ์ดํ„ฐ ์กฐํšŒ ๊ธฐ๋Šฅ
INSERT๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ
UPDATE๋ฐ์ดํ„ฐ ์ˆ˜์ • ๊ธฐ๋Šฅ
DELETE๋ฐ์ดํ„ฐ ์‚ญ์ œ ๊ธฐ๋Šฅ
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ์ž๊ฐ€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ์งˆ์˜์–ด๋ฅผ ํ†ตํ•˜์—ฌ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์งˆ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ์ž์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ๊ฐ„์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

DCL(Data Control Language) - ๋ฐ์ดํ„ฐ ์ œ์–ด์–ด

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ๊ฐ์ฒด์— ๊ถŒํ•œ์„ ์ฃผ๋Š”๋“ฑ์˜ ์—ญํ• ์„ ํ•˜๋Š” ์–ธ์–ด๋ฅผ ๋งํ•œ๋‹ค.

์ข…๋ฅ˜์—ญํ• 
GRANTํŠน์ • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ์ž์—๊ฒŒ ํŠน์ • ์ž‘์—…์— ๋Œ€ํ•œ ์ˆ˜ํ–‰๊ถŒํ•œ ๋ถ€์—ฌ ํ•œ๋‹ค.
REVOKEํŠน์ • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ์ž์—๊ฒŒ ํŠน์ • ์ž‘์—…์— ๋Œ€ํ•œ ์ˆ˜ํ–‰ ๊ถŒํ•œ์„ ๋ฐ•ํƒˆ, ํšŒ์ˆ˜ ํ•œ๋‹ค.
COMMITํŠธ๋žœ์žญ์…˜์˜ ์ž‘์—… DB์— ๋ฐ˜์˜ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
ROLLBACKํŠธ๋žœ์žญ์…˜์˜ ์ž‘์—…์„ ์ทจ์†Œ ๋ฐ ์›๋ž˜๋ž˜ ๋ณต๊ตฌํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ์ œ์–ดํ•˜๋Š” ์–ธ์–ด์ด๋‹ค.
  • ๋ฐ์ดํ„ฐ์˜ ๋ณด์•ˆ, ๋ฌด๊ฒฐ์„ฑ, ํšŒ๋ณต, ๋ณ‘ํ–‰ ์ˆ˜ํ–‰์ œ์–ด ๋“ฑ์„ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

2. DB ์„ค๊ณ„

์˜ˆ์ œ) PROD ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

Session ํ…Œ์ด๋ธ”

์ปฌ๋Ÿผํƒ€์ž…์†์„ฑ
idintNOT NULL
AUTO_INCREMENT
PRIMARY KEY
user_idintNOT NULL
createdtimestampNOT NULL
DEFAULT CURRENT_TIMESTAMP
channel_idintNOT NULL
FOREIGN KEY

Channel ํ…Œ์ด๋ธ”

์ปฌ๋Ÿผํƒ€์ž…์†์„ฑ
idintNOT NULL
AUTO_INCREMENT
PRIMARY KEY
channelvarchar(32)NOT NULL

Select ๋ฌธ์„ ๋Œ๋ฆฌ๊ธฐ ์ „์—

SHOW DATABASE; -- ํ˜„์žฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค€๋‹ค.
USE PROD; -- ํ•ด๋‹น ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
SHOW TABLES; -- ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ” ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค€๋‹ค.   

3. Select

ํ…Œ์ด๋ธ”์—์„œ ๋ ˆ์ฝ”๋“œ๋“ค(ํ˜น์€ ๋ ˆ์ฝ”๋“œ์ˆ˜)์„ ์ฝ์–ด์˜ค๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

WHERE๋ฅผ ์‚ฌ์šฉํ•ด ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ ˆ์ฝ”๋“œ

select(1) - ๊ธฐ๋ณธ ๊ตฌ์กฐ

SELECT ํ•„๋“œ์ด๋ฆ„1, ํ•„๋“œ์ด๋ฆ„2, โ€ฆ
FROM ํ…Œ์ด๋ธ”์ด๋ฆ„
WHERE ์„ ํƒ์กฐ๊ฑด
GROUP BY ํ•„๋“œ์ด๋ฆ„1, ํ•„๋“œ์ด๋ฆ„2, ...
ORDER BY ํ•„๋“œ์ด๋ฆ„ [ASC|DESC] -- ํ•„๋“œ ์ด๋ฆ„ ๋Œ€์‹ ์— ์ˆซ์ž ์‚ฌ์šฉ ๊ฐ€๋Šฅ
LIMIT N;

select(2) - from

select * -- *๋Š” ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ง€์นญํ•˜๋Š” ํ‘œํ˜„
from prod.session; -- ์•ž์„œ USE prod;๋ฅผ ์ˆ˜ํ–‰ํ–ˆ๋‹ค๋ฉด FROM session๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • prod.session์˜ ํ…Œ์ด๋ธ”์— ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

select(3) - from

SELECT id, user_id, channel_id -- 3๊ฐœ์˜ ์ปฌ๋Ÿผ๊ฐ’๋“ค์„ ๊ฐ€์ ธ์˜จ๋‹ค. 
FROM prod.session;

select(3) - from, LIMIT[๊ฐฏ ์ˆ˜ ์ œํ•œ]

SELECT *
FROM prod.session
LIMIT 10; -- Limit ๋ฅผ ์“ฐ๊ฒŒ๋˜๋ฉด N๊ฐœ ๋งŒํผ๋งŒ ์ถœ๋ ฅํ•œ๋‹ค.

select(4) - from, DISTINCT[์ค‘๋ณต์ œ๊ฑฐ]

SELECT DISTINCT channel_id -- ์œ ์ผํ•œ ์ฑ„๋„ ID๋ฅผ ์•Œ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
FROM prod.session;

select(5) - from, COUNT()[ํ•„๋“œ๋ช… Countํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜]

  • COUNT(ํ•„๋“œ ์ด๋ฆ„ or ํ•„๋“œ index) ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
SELECT COUNT(1) -- ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ ์ˆ˜ ์นด์šดํŠธ. COUNT(*). ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ
FROM prod.session;

SELECT * -- channel ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ๋“ค์„ ํ‘œ์‹œ
FROM prod.channel;

-- ์ฑ„๋„์ด 1, 5์ธ ์ฑ„๋„๋งŒ์„ ๋ฌถ์–ด์„œ ์ถœ๋ ฅ
select channel_id, COUNT(1) 
from prod.session
where channel_id = 5 or channel_id = 1
group by channel_id;

CASE WHEN

  • ํ•„๋“œ ๊ฐ’์˜ ๋ณ€ํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    • CASE WHEN ์กฐ๊ฑด THEN ์ฐธ์ผ๋•Œ ๊ฐ’ ELSE ๊ฑฐ์ง“์ผ๋•Œ ๊ฐ’ END ํ•„๋“œ์ด๋ฆ„
-- ์ฑ„๋„ ID๋ณ„๋กœ ๊ฐฏ์ˆ˜์™€ type์„ ์ •์˜ํ•˜๊ณ  ๋ฌถ์€๋‹ค์Œ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ถœ๋ ฅ
select channel_id, COUNT(1),
	CASE
		when channel_id in (1,5,6) then 'Social-Media'
        when channel_id in (2,4) then 'Search-Engine'
        else 'Something-Engine'
	END channel_type
from prod.session
group by channel_id
order by count(1); -- 1์€ ์—ฌ๊ธฐ์„œ channel_id๋ฅผ ์˜๋ฏธํ•œ๋‹ค. + ์˜ค๋ฆ„์ฐจ์ˆœ

NULL

๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ƒ์ˆ˜. 0 ํ˜น์€ ""๊ณผ๋Š” ๋‹ค๋ฆ„

  • ํ•„๋“œ ์ง€์ •์‹œ ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ NULL๋กœ ์ง€์ • ๊ฐ€๋Šฅ
    • ํ…Œ์ด๋ธ” ์ •์˜์‹œ ๋””ํดํŠธ ๊ฐ’์œผ๋กœ๋„ ์ง€์ • ๊ฐ€๋Šฅ
  • ์–ด๋–ค ํ•„๋“œ์˜ ๊ฐ’์ด NULL์ธ์ง€ ์•„๋‹Œ์ง€ ๋น„๊ต๋Š” ํŠน์ˆ˜ํ•œ ๋ฌธ๋ฒ•์„ ํ•„์š”๋กœ ํ•จ
    • field1 is NULL ํ˜น์€ field1 is not NULL
  • NULL์ด ์‚ฌ์น™์—ฐ์‚ฐ์— ์‚ฌ์šฉ๋˜๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋Š”?
    • SELECT 0 + NULL, 0 - NULL, 0 * NULL, 0/NULL

COUNT ํ•จ์ˆ˜

ํ—ท๊ฐˆ๋ฆฌ๋Š” count ํ•จ์ˆ˜ ์˜ˆ์‹œ

๊ทธ๋ฃน(aggregate) ํ•จ์ˆ˜์— ํ•ด๋‹นํ•œ๋‹ค.

  • ์˜ˆ์‹œ ํ…Œ์ด๋ธ”
value
NULL
1
1
0
0
4
3
SELECT COUNT(1) FROM prod.count_test;
-- ์ •๋‹ต : 7๊ฐœ (null ๊ฐ’์„ ํฌํ•จํ•œ๋‹ค.)

SELECT COUNT(0) FROM prod.count_test;
-- ์ •๋‹ต : 7๊ฐœ (null ๊ฐ’์„ ํฌํ•จํ•œ๋‹ค.)

SELECT COUNT(NULL) FROM prod.count_test;
-- ์ •๋‹ต : 0๊ฐœ (null์ด๋ฉด count๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค.)

SELECT COUNT(value) FROM prod.count_test;
-- ์ •๋‹ต : 6๊ฐœ (ํ•„๋“œ๊ฐ’์„ ๋„ฃ์œผ๋ฉด null๊ฐ’์„ ์ œ์™ธํ•˜๊ณ  count ํ•œ๋‹ค.)

SELECT COUNT(DISTINCT value) FROM prod.count_test;
-- ์ •๋‹ต : 4๊ฐœ (์ค‘๋ณต ๊ฐ’ ์ œ์™ธ + null๊ฐ’ ์ œ์™ธ)

WHERE

  • IN
    • WHERE channel_id in (3, 4)
      • WHERE channel_id = 3 OR channel_id = 4
    • NOT IN
  • LIKE
    • LIKE: ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ณ„ ์—†์ด ๋ฌธ์ž์—ด ๋งค์นญ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์คŒ
    • WHERE channel LIKE 'G%' -> 'G*'
    • WHERE channel LIKE '%o%' -> 'o'
    • NOT LIKE
  • BETWEEN
    • ๋‚ ์งœ ๋ฒ”์œ„์— ์‚ฌ์šฉ ๊ฐ€๋Šฅ
-- where ์กฐ๊ฑด
select count(1)
from prod.channel
where channel like 'G%'; -- G๋กœ ์‹œ์ž‘ํ•˜๋Š” channel๋งŒ

select channel
from prod.channel
where channel not like '%o%'; -- o๋ผ๋Š” ๋ฌธ์ž๊ฐ€ ํฌํ•จํ•˜์ง€ ์•Š๋Š” channel

STRING ํ•จ์ˆ˜

  • LEFT(str, N)
  • REPLACE(str, exp1, exp2)
  • UPPER(str)
  • LOWER(str)
  • LENGTH(str)
  • LPAD, RPAD
  • SUBSTRING
  • CONCAT
-- String ํ•จ์ˆ˜๋ฅผ ์จ๋ณด์ž
select 
	length(channel), -- ๊ธธ์ด
    upper(channel),  -- ๋Œ€๋ฌธ์ž ๋ณ€ํ™˜
    lower(channel),  -- ์†Œ๋ฌธ์ž ๋ณ€ํ™˜
    left(channel,4), -- ์™ผ์ชฝ๋ถ€ํ„ฐ 4๊ฐœ๋งŒ ์ถœ๋ ฅ
    rpad(channel,15,'-') --15์ž๋ฆฌ ์ค‘ ๋นˆ์นธ์€ ์˜ค๋ฅธ์ชฝ์— - ๋กœ ์ฑ„์›€
from prod.channel
order by length(channel); -- ๊ธธ์ด๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ   

DATE ํ•จ์ˆ˜

  • ์˜ˆ์‹œ 1
-- Date ํ•จ์ˆ˜ ์จ๋ณด๊ธฐ
select
	created, convert_tz(created, 'GMT','Asia/Seoul') seoul_time,
	year(created) y, quarter(created) q, month(created) m, monthname(created) mnn,
    date(created) d, hour(created) h, minute(created), second(created) s
from prod.session
limit 10;
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2021-08-16 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 55 33
  • ์˜ˆ์‹œ 2
select created,
	datediff(now(), created) gap_in_days,
    date_add(created, interval 10 day) ten_days_after_created
from prod.session
limit 10;
แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2021-08-16 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1 58 55
  • ์˜ˆ์‹œ 3
select str_to_date('11,8,2021', '%d,%m,%y');
-- ๋ฌธ์ž์—ด ํ˜• ๋ณ€ํ™˜

Type Casting

  • cast ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ
    • cast(category as float)
    • convert(expression, float)
SELECT cast('100.0' as float), convert('100.0', float);
-- 100, 100 ์„ ์ถœ๋ ฅํ•œ๋‹ค. 

3. Group by - ๊ทธ๋ฃน(aggregate) ํ•จ์ˆ˜

GROUP BY ์ ˆ์€ ์„ ํƒ๋œ ๋ ˆ์ฝ”๋“œ์˜ ์ง‘ํ•ฉ์„ ํ•„๋“œ์˜ ๊ฐ’์ด๋‚˜ ํ‘œํ˜„์‹์— ์˜ํ•ด ๊ทธ๋ฃนํ™”ํ•œ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, GROUP BY ์ ˆ์€ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์„ ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์˜ ํฌ๊ธฐ๋ฅผ ์ค„์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • GROUP BY ์ ˆ์€ SELECT ๋ฌธ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ORDER BY์™€ GROUP BY
    • ํฌ์ง€์…˜ ๋ฒˆํ˜ธ vs. ํ•„๋“œ ์ด๋ฆ„
    • GROUP BY 1 == GROUP BY mon == GROUP BY LEFT(s.created, 7)
-- ์›”๋ณ„ ์„ธ์…˜ ์ˆ˜๋ฅผ ๊ณ„์‚ฐ
select 
	left(created,7) mon,
    count(1) as session_count
from prod.session
group by 1 -- mon์œผ๋กœ group
order by 1; -- mon์œผ๋กœ ASC 


-- ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋œ ์ฑ„๋„์€ ๋ฌด์—‡์ธ๊ฐ€?
select 
	channel_id,
    count(1) as session_count,
    count(distinct user_id) as user_count
from prod.session
group by 1
order by 2 desc;

-- ๊ฐ€์žฅ ๋งŽ์€ ์„ธ์…˜์„ ๋งŒ๋“ค์–ด๋‚ธ ์‚ฌ์šฉ์ž ID๋Š” ๋ฌด์—‡์ธ๊ฐ€?
select
	user_id,
    count(1) as user_count
from prod.session
group by 1
order by 2 desc
limit 1;

-- ์›”๋ณ„ ์œ ๋‹ˆํฌํ•œ ์‚ฌ์šฉ์ž ์ˆ˜
select
	left(created, 7) as mon,
    count(distinct user_id) as user_count
from prod.session
group by 1
order by 1;

-- session ์•„์ด๋””๋ณ„, ์‚ฌ์šฉ์ž๋ณ„ ํ†ต๊ณ„
select s.id, s.user_id, s.created, s.channel_id, c.channel
from prod.session s
join prod.channel c on c.id = s.channel_id;
GROUP BY 1, 2
ORDER BY 1 DESC, 2;

-- ์›”๋ณ„, ์ฑ„๋„๋ณ„ ์œ ๋‹ˆํฌํ•œ ์‚ฌ์šฉ์ž ์ˆ˜
select
	left(s.created, 7) as mon,
    c.channel,
    count(distinct s.user_id) as mau
from prod.session s
join prod.channel c on c.id = s.channel_id
group by 1,2
order by 1 desc, 2;
profile
๊พธ์ค€ํ•œ ๊ธฐ๋ก์„ ํ•˜์ž

0๊ฐœ์˜ ๋Œ“๊ธ€