็คผๅ ็ ๆฅ่กจ๏ผๆฐๆฎ้ฉฑๅจ่ฟ่ฅๅณ็ญ๏ผๆทฑๅบฆๆๆฏ็ฏ๏ผ
ๆฌๆๆฏ็คผๅ ็ ็ณปๅ็็ฌฌ6็ฏ๏ผไนๆฏๆๅไธ็ฏใๅไบ็ฏๆไปฌๅๅซไป็ปไบ็คผๅ ็ ็ๅบ็กๆถๆใ็ๆ็ฎๆณใๆน้็ฎก็ใๅ ๆขไบๅกๅๅๅฒ่ฟฝๆบฏใไปๅคฉ๏ผๆไปฌๆฅ่่ๆดไธช็ณป็ป็"็ผ็"โโๆฅ่กจ็ณป็ป๏ผ็็ๅฆไฝ้่ฟๆฐๆฎ้ฉฑๅจ่ฟ่ฅๅณ็ญใ
ไธใ็คผๅ ็ ๆฐๆฎ็ไปทๅผ
่ฟ่ฅๆดปๅจ็ๆๆๅฆไฝ๏ผ็ฉๅฎถๅๆฌขไปไนๅฅๅฑ๏ผๆธ ้ๆๆพ็ROIๆๆ ท๏ผ
่ฟไบ้ฎ้ข๏ผๅ ้ "ๆ่ง"ๆฏๅ็ญไธไบ็ใ
็คผๅ ็ ็ณป็ป็็ๆญฃไปทๅผ๏ผไธๅจไบๅฎ่ฝๅๅบๅคๅฐ็คผๅ ๏ผ่ๅจไบๅฎ่ฝไธบ่ฟ่ฅๅณ็ญๆไพไปไนๆฐๆฎๆฏๆใๆฏไธๆฌกๅ ๆขใๆฏไธไธช็ ็็ๆๅไฝฟ็จ๏ผ้ฝๆฏไธ้ขๆฐๆฎ็็ ใๆๅฎไปฌไธฒ่ตทๆฅ๏ผๅฐฑๆฏไธๆกๅฎๆด็่ฟ่ฅๆดๅฏ้กน้พใ
- ๆดปๅจๆๆ๏ผๆๆพไบ10000ไธช็ ๏ผๅฎ้ ๅ ๆขไบๅคๅฐ๏ผๅ ๆข็ๆฏ5%่ฟๆฏ80%๏ผ่ฟ็ดๆฅๅๆ ไบๆดปๅจ็ๅธๅผๅใ
- ๆธ ้่ดจ้๏ผAๆธ ้็็ ่ขซๆขๅ ไบ๏ผBๆธ ้่ฟๆไธๅๆฒก็จๅฎใไธๆฌกๆๆพ๏ผ่ตๆบๅพๅช้ๅพๆ๏ผ
- ็ฉๅฎถ่กไธบ๏ผๅ ๆข้ซๅณฐๆๅจไปไนๆถๅ๏ผๅๆจ่ฟๆฏๆไธ๏ผๅทฅไฝๆฅ่ฟๆฏๅจๆซ๏ผ่ฟๅณๅฎไบๆจ้ๆถๆบใ
- ้ฃ้ฉ้ข่ญฆ๏ผๆไธช็ ๅจ1ๅ้ๅ ่ขซๅ ๆขไบ100ๆฌก๏ผๅผๅธธ่กไธบ๏ผ้่ฆไปๅ ฅ่ฐๆฅใ
ไผ ็ป็่ฟ่ฅๅณ็ญ๏ผๅพๅพไพ่ต็ป้ช๏ผ"ๆ่งๅพ่ฟไธชๆดปๅจไผ็ซ"ใ"ไธๆฌก็ฑปไผผ็ๆดปๅจๆๆไธ้"ใไฝ็ป้ชๆๅฑ้ๆงโโๅธๅบๅจๅ๏ผ็ฉๅฎถๅจๅ๏ผไฝ ็็ป้ชๅฏ่ฝๅทฒ็ป่ฟๆถไบใ
ๆฐๆฎ้ฉฑๅจ็่ฟ่ฅ๏ผๆฏ่ฎฉๆฐๅญ่ฏด่ฏใไธๆฏ"ๆ่งๅพ"๏ผ่ๆฏ"ๆฐๆฎๆพ็คบ"ใ่ฟไธๆฏๅฆๅฎ็ป้ช็ไปทๅผ๏ผ่ๆฏ็จๆฐๆฎ้ช่ฏ็ป้ช๏ผ็จๆฐๆฎไฟฎๆญฃๅ่งใ
ๆฏไธๆฌกๆดปๅจ๏ผ้ฝๆฏไธๆฌกๆฐๆฎ็งฏ็ดฏใไปๅนด็"ๆฅ่ๆดปๅจ"ๆฐๆฎ๏ผๅฏไปฅๅๅปๅนดๅฏนๆฏ๏ผไปๅนด็"618ๆดปๅจ"ๆฐๆฎ๏ผๅฏไปฅๆๅฏผๆๅนด็็ญ็ฅ่งๅใ
ๆฐๆฎ่ถ็งฏ็ดฏ๏ผไปทๅผ่ถๅคงใไธไธช่ฟ่กไบไธๅนด็็คผๅ ็ ็ณป็ป๏ผๆฒๆทไธๆฅ็ไธๅชๆฏๅ ็พไธๆกๅ ๆข่ฎฐๅฝ๏ผ่ๆฏๅฏน็จๆท่กไธบใๅธๅบ่งๅพ็ๆทฑๅป็่งฃใ่ฟไบ็่งฃ๏ผๆฏ็ซไบๅฏนๆ็ญๆๅ ๆ ๆณๅคๅถ็ๆคๅๆฒณใ
็ฌฌไธๅฑ๏ผ็ๆฐๆฎใ็ฅ้ๅ็ไบไปไน๏ผ่ฟๆฏๆๅบ็ก็ใ ็ฌฌไบๅฑ๏ผๆๅๅ ใ็ฅ้ไธบไปไนๅ็๏ผ่ฟ้่ฆๅๆ่ฝๅใ ็ฌฌไธๅฑ๏ผ่ฝ้ขๆตใ็ฅ้ๅฐ่ฆๅ็ไปไน๏ผ่ฟ้่ฆๅปบๆจก่ฝๅใ
ๅคงๅคๆฐๅข้ๅ็ๅจ็ฌฌไธๅฑ๏ผๅฐๆฐๅข้่ฝๅฐ็ฌฌไบๅฑ๏ผ่ฝๅฐ็ฌฌไธๅฑ็ๅคๆฏ้บ่งใๆฅ่กจ็ณป็ป็็ฎๆ ๏ผๆฏๅธฎๅฉๅข้ไป็ฌฌไธๅฑ่ตฐๅ็ฌฌไบๅฑ๏ผๆ็ป่พพๅฐ็ฌฌไธๅฑใ
ไบใๆฐๆฎไปๅบๆถๆ่ฎพ่ฎก
ๅจๆทฑๅ ฅๆๆ ๅๆฅ่กจไนๅ๏ผๆไปฌ้่ฆๅ ็่งฃๆฐๆฎๆฏๅฆไฝ่ขซ็ป็ปๅๅญๅจ็ใ่ฟๅฐฑๅๅปบๆฟๅญ๏ผๅ ่ฆๆๅฅฝๅฐๅบใ
2.1 ๆฐๆฎๅๅฑๆถๆ
็ฐไปฃๆฐๆฎไปๅบ้ๅธธ้็จๅๅฑๆถๆ๏ผๆๆฐๆฎๆ็ งๅค็้ถๆฎตๅๆไธๅ็ๅฑๆฌก๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ADS (ๅบ็จๆฐๆฎๅฑ) โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ ่ฟ่ฅๆฅ่กจ โ โ ๅฎๆถ็ๆง โ โ ๆฐๆฎAPI โ โ ๅฏผๅบๆๅก โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ DWS (ๆฑๆปๆฐๆฎๅฑ) โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ ๆดปๅจๆฅๆฑๆป่กจ โ โ ๆธ ้ๆฅๆฑๆป่กจ โ โ ็จๆทๆฅๆฑๆป่กจ โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ DWD (ๆ็ปๆฐๆฎๅฑ) โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ ๅ
ๆขๆ็ปๅฎฝ่กจ โ โ ็ ็ๅฝๅจๆ่กจ โ โ ็จๆท่กไธบ่กจ โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ODS (ๅๅงๆฐๆฎๅฑ) โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ ๅ
ๆขๆตๆฐด่กจ โ โ ็ ็ๆ่ฎฐๅฝ่กจ โ โ ็จๆทๅบ็ก่กจ โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่ฟไธๅฑ็ดๆฅๅๆญฅไธๅกๆฐๆฎๅบ็ๅๅงๆฐๆฎ๏ผไฟๆๅไธๅก็ณป็ปไธ่ด็็ปๆใๅฏไปฅๆๅฎๆณ่ฑกๆไธไธช"ๆฐๆฎๅคไปฝไปๅบ"๏ผไธๅไปปไฝๅ ๅทฅๅค็ใ
-- ODSๅฑ๏ผๅ
ๆขๆตๆฐด่กจ๏ผๅๅงๆฐๆฎ๏ผ
CREATE TABLE ods_gift_code_redeem_log (
id BIGINT PRIMARY KEY,
code_id BIGINT NOT NULL COMMENT '็คผๅ
็ ID',
code VARCHAR(32) NOT NULL COMMENT '็คผๅ
็ ',
user_id BIGINT NOT NULL COMMENT '็จๆทID',
activity_id BIGINT NOT NULL COMMENT 'ๆดปๅจID',
channel_id BIGINT COMMENT 'ๆธ ้ID',
reward_id BIGINT NOT NULL COMMENT 'ๅฅๅฑ้
็ฝฎID',
redeem_time DATETIME NOT NULL COMMENT 'ๅ
ๆขๆถ้ด',
redeem_ip VARCHAR(45) COMMENT 'ๅ
ๆขIP',
device_id VARCHAR(64) COMMENT '่ฎพๅคID',
status TINYINT NOT NULL COMMENT '็ถๆ๏ผ1ๆๅ 2ๅคฑ่ดฅ',
fail_reason VARCHAR(255) COMMENT 'ๅคฑ่ดฅๅๅ ',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_code_id (code_id),
INDEX idx_user_id (user_id),
INDEX idx_activity_id (activity_id),
INDEX idx_redeem_time (redeem_time)
) COMMENT 'ๅ
ๆขๆตๆฐดๅๅง่กจ';
่ฟไธๅฑๅฏนๅๅงๆฐๆฎ่ฟ่กๆธ ๆดใ่ฝฌๆขๅๆดๅ๏ผๅฝขๆๅฎฝ่กจใๅฎฝ่กจ็ๆๆๆฏๆๅคไธช็ธๅ ณ่กจ็ๆฐๆฎๅๅนถๅฐไธ่ตท๏ผๆนไพฟๅ็ปญๅๆใ
-- DWDๅฑ๏ผๅ
ๆขๆ็ปๅฎฝ่กจ๏ผ็ป่ฟๆธ
ๆดๅๅ
ณ่๏ผ
CREATE TABLE dwd_gift_code_redeem_detail (
-- ๅ
ๆขๅบ็กไฟกๆฏ
redeem_id BIGINT PRIMARY KEY,
code_id BIGINT NOT NULL,
code VARCHAR(32) NOT NULL,
user_id BIGINT NOT NULL,
-- ๆดปๅจ็ปดๅบฆ
activity_id BIGINT NOT NULL,
activity_name VARCHAR(128) COMMENT 'ๆดปๅจๅ็งฐ',
activity_type VARCHAR(32) COMMENT 'ๆดปๅจ็ฑปๅ๏ผNEW_USER/DAILY/CHANNEL',
activity_start_time DATETIME COMMENT 'ๆดปๅจๅผๅงๆถ้ด',
activity_end_time DATETIME COMMENT 'ๆดปๅจ็ปๆๆถ้ด',
-- ๆธ ้็ปดๅบฆ
channel_id BIGINT,
channel_name VARCHAR(64) COMMENT 'ๆธ ้ๅ็งฐ',
channel_type VARCHAR(32) COMMENT 'ๆธ ้็ฑปๅ๏ผSOCIAL/ADS/PARTNER',
-- ๅฅๅฑ็ปดๅบฆ
reward_id BIGINT NOT NULL,
reward_name VARCHAR(128) COMMENT 'ๅฅๅฑๅ็งฐ',
reward_type VARCHAR(32) COMMENT 'ๅฅๅฑ็ฑปๅ๏ผGOLD/ITEM/SKIN',
reward_value DECIMAL(18,2) COMMENT 'ๅฅๅฑไปทๅผ๏ผ็ญไปทไบบๆฐๅธ๏ผ',
-- ็จๆท็ปดๅบฆ
user_register_time DATETIME COMMENT '็จๆทๆณจๅๆถ้ด',
user_level INT COMMENT '็จๆท็ญ็บง',
user_vip_level INT COMMENT 'VIP็ญ็บง',
is_new_user TINYINT COMMENT 'ๆฏๅฆๆฐ็จๆท๏ผๆณจๅ7ๅคฉๅ
๏ผ',
user_total_recharge DECIMAL(18,2) COMMENT 'ๅๅฒๅ
ๅผๆป้ข',
-- ๆถ้ด็ปดๅบฆ
redeem_time DATETIME NOT NULL,
redeem_date DATE COMMENT 'ๅ
ๆขๆฅๆ',
redeem_hour TINYINT COMMENT 'ๅ
ๆขๅฐๆถ๏ผ0-23๏ผ',
day_of_week TINYINT COMMENT 'ๆๆๅ ๏ผ1-7๏ผ',
is_weekend TINYINT COMMENT 'ๆฏๅฆๅจๆซ',
-- ่ฎพๅคๅไฝ็ฝฎ
redeem_ip VARCHAR(45),
device_id VARCHAR(64),
device_type VARCHAR(32) COMMENT '่ฎพๅค็ฑปๅ๏ผiOS/Android',
province VARCHAR(32) COMMENT '็ไปฝ',
city VARCHAR(32) COMMENT 'ๅๅธ',
-- ๅ
ๆข็ปๆ
status TINYINT NOT NULL,
fail_reason VARCHAR(255),
-- ETLๅญๆฎต
etl_time DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_activity_date (activity_id, redeem_date),
INDEX idx_channel_date (channel_id, redeem_date),
INDEX idx_user_date (user_id, redeem_date),
INDEX idx_redeem_date (redeem_date)
) COMMENT 'ๅ
ๆขๆ็ปๅฎฝ่กจ';
่ฟไธๅฑๅฏนๆ็ปๆฐๆฎ่ฟ่ก่ๅๆฑๆป๏ผๆ็ งไธๅ็ๅๆ็ปดๅบฆ้ขๅ ่ฎก็ฎๅฅฝๆๆ ใ่ฟๆ ทๆฅ่ฏขๆฅ่กจๆถๅฐฑไธ้่ฆๆฏๆฌก้ฝๆซๆๅคง้ๆ็ปๆฐๆฎ๏ผๆง่ฝไผๅฅฝๅพๅคใ
-- DWSๅฑ๏ผๆดปๅจๆฅๆฑๆป่กจ
CREATE TABLE dws_activity_daily_summary (
activity_id BIGINT NOT NULL,
stat_date DATE NOT NULL,
-- ็ ็็ป่ฎก
total_codes INT COMMENT '็ดฏ่ฎก็ๆ็ ๆฐ',
available_codes INT COMMENT 'ๅฏ็จ็ ๆฐ',
redeemed_codes INT COMMENT 'ๅทฒๅ
ๆข็ ๆฐ',
code_usage_rate DECIMAL(5,2) COMMENT '็ ไฝฟ็จ็๏ผ%๏ผ',
-- ๅ
ๆข็ป่ฎก
total_redeems INT COMMENT 'ๆปๅ
ๆขๆฌกๆฐ',
success_redeems INT COMMENT 'ๆๅๅ
ๆขๆฌกๆฐ',
fail_redeems INT COMMENT 'ๅคฑ่ดฅๅ
ๆขๆฌกๆฐ',
redeem_success_rate DECIMAL(5,2) COMMENT 'ๅ
ๆขๆๅ็๏ผ%๏ผ',
-- ็จๆท็ป่ฎก
unique_users INT COMMENT '็ฌ็ซๅ
ๆข็จๆทๆฐ',
new_users INT COMMENT 'ๆฐ็จๆทๆฐ',
old_users INT COMMENT '่็จๆทๆฐ',
new_user_ratio DECIMAL(5,2) COMMENT 'ๆฐ็จๆทๅ ๆฏ๏ผ%๏ผ',
avg_redeems_per_user DECIMAL(5,2) COMMENT 'ไบบๅๅ
ๆขๆฌกๆฐ',
-- ๆถ้ด็ป่ฎก
peak_hour TINYINT COMMENT 'ๅณฐๅผๅ
ๆขๅฐๆถ',
peak_hour_redeems INT COMMENT 'ๅณฐๅผๅฐๆถๅ
ๆข้',
avg_redeem_interval INT COMMENT 'ๅนณๅๅ
ๆข้ด้๏ผ็ง๏ผ',
-- ไปทๅผ็ป่ฎก
total_reward_value DECIMAL(18,2) COMMENT 'ๅๆพๅฅๅฑๆปไปทๅผ',
avg_reward_value DECIMAL(18,2) COMMENT 'ๅนณๅๅฅๅฑไปทๅผ',
-- ๅ็ฏๆฏ
redeem_dod DECIMAL(5,2) COMMENT 'ๅ
ๆข้ๆฅ็ฏๆฏ๏ผ%๏ผ',
redeem_wow DECIMAL(5,2) COMMENT 'ๅ
ๆข้ๅจๅๆฏ๏ผ%๏ผ',
-- ETLๅญๆฎต
etl_time DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (activity_id, stat_date),
INDEX idx_stat_date (stat_date)
) COMMENT 'ๆดปๅจๆฅๆฑๆป่กจ';
่ฟไธๅฑๆฏ็ดๆฅ้ขๅๆฅ่กจๅAPI็ๆฐๆฎๅฑ๏ผๆฐๆฎๆ ผๅผๅฎๅ จๆ็ งๅ็ซฏๅฑ็คบ้ๆฑๆฅ่ฎพ่ฎกใ
-- ADSๅฑ๏ผๅฎๆถ็ๆงๆๆ ่กจ
CREATE TABLE ads_realtime_monitor (
metric_name VARCHAR(64) PRIMARY KEY,
metric_value DECIMAL(18,2),
metric_unit VARCHAR(16),
compare_value DECIMAL(18,2) COMMENT 'ๅฏนๆฏๅผ๏ผๆจๆฅๅๆ/ไธๅจๅๆ๏ผ',
change_rate DECIMAL(5,2) COMMENT 'ๅๅ็๏ผ%๏ผ',
trend VARCHAR(8) COMMENT '่ถๅฟ๏ผUP/DOWN/FLAT',
status VARCHAR(16) COMMENT '็ถๆ๏ผNORMAL/WARNING/ALERT',
update_time DATETIME,
INDEX idx_update_time (update_time)
) COMMENT 'ๅฎๆถ็ๆงๆๆ ่กจ';
2.2 ๆฐๆฎๆต่ฝฌ็ฎก้
ๆฐๆฎไปไธๅก็ณป็ปๆตๅๆฅ่กจ็ณป็ป๏ผ้่ฆ็ป่ฟไธไธชETL๏ผExtract-Transform-Load๏ผ็ฎก้๏ผ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ ไธๅกๆฐๆฎๅบ โโโโโถโ ๆถๆฏ้ๅ โโโโโถโ ๆตๅค็ๅผๆ โโโโโถโ ๅฎๆถๆฐไป โ
โ (MySQL) โ โ (Kafka) โ โ (Flink) โ โ (ClickHouse) โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ โ
โ โโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโถโ ๆนๅค็ๅผๆ โโโโโโโโโโโโโโโโโโโโโโโโโ
โ (Spark) โ
โโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโ
โ ็ฆป็บฟๆฐไป โ
โ (Hive/Doris) โ
โโโโโโโโโโโโโโโโ
2.3 ๆฐๆฎ่ดจ้ไฟ้
ๆฐๆฎ่ดจ้ๆฏๆฅ่กจ็ณป็ป็็ๅฝ็บฟใๅๅพ่ฟ๏ผๅๅพๅบโโๅฆๆๆบๆฐๆฎๆ้ฎ้ข๏ผๅๆผไบฎ็ๆฅ่กจไนๆฏ่ฏฏๅฏผใ
-- ๆฐๆฎๅฎๆดๆงๆฃๆฅ๏ผๆฏๅฆๆไธขๅคฑๆฐๆฎ
SELECT
DATE(redeem_time) as stat_date,
COUNT(*) as record_count,
COUNT(DISTINCT user_id) as unique_users
FROM ods_gift_code_redeem_log
WHERE redeem_time >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
GROUP BY DATE(redeem_time)
HAVING record_count < 100 OR unique_users < 10; -- ้ๅผๅฏๆ นๆฎไธๅก่ฐๆด
-- ๆฐๆฎไธ่ดๆงๆฃๆฅ๏ผๅ
ๆข่ฎฐๅฝๅ็ ็็ถๆๆฏๅฆไธ่ด
SELECT
r.code_id,
r.user_id,
r.redeem_time,
c.status as code_status,
CASE WHEN c.status = 1 AND r.status = 1 THEN 'OK'
WHEN c.status = 0 AND r.status = 2 THEN 'OK'
ELSE 'INCONSISTENT' END as check_result
FROM ods_gift_code_redeem_log r
LEFT JOIN gift_code c ON r.code_id = c.id
WHERE r.redeem_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
HAVING check_result = 'INCONSISTENT';
-- ๆฐๆฎๅๆถๆงๆฃๆฅ๏ผETLๆฏๅฆๆๆถๅฎๆ
SELECT
table_name,
max_etl_time,
TIMESTAMPDIFF(MINUTE, max_etl_time, NOW()) as delay_minutes
FROM (
SELECT 'dwd_gift_code_redeem_detail' as table_name,
MAX(etl_time) as max_etl_time
FROM dwd_gift_code_redeem_detail
UNION ALL
SELECT 'dws_activity_daily_summary' as table_name,
MAX(etl_time) as max_etl_time
FROM dws_activity_daily_summary
) t
HAVING delay_minutes > 120; -- ่ถ
่ฟ2ๅฐๆถๆฅ่ญฆ
ไธใๆ ธๅฟๆฐๆฎๆๆ
่ฆๅๅฅฝๆฅ่กจ๏ผ้ฆๅ ่ฆๆ็กฎ๏ผๅชไบๆๆ ๆฏๅผๅพๅ ณๆณจ็๏ผ
3.1 ๅ ๆข็ฑปๆๆ
่ฟๆฏๆๆ ธๅฟ็ๆๆ ใๅ ๆข็ไฝ๏ผ่ฏดๆๆดปๅจๅธๅผๅไธ่ถณ๏ผๆ่ ๆๆพๆธ ้ไธๅฏนใๅ ๆข็่ฟ้ซ๏ผๆฏๅฆ่ถ ่ฟ100%๏ผ๏ผๅ้่ฆ่ญฆๆโโๅฏ่ฝๆฏ็ ่ขซๆณ้ฒๆๆปฅ็จไบใ
ไฝๅ ๆข็ไธๆฏ่ถ้ซ่ถๅฅฝใ100%็ๅ ๆข็๏ผๆๅณ็ๆฒกๆๅไฝ๏ผๆฒกๆๅฎน้็ฉบ้ดใๅฆๆๆธ ้้่ฆ่ฟฝๅ ๆๆพ๏ผๆไธๅทฒ็ปๆฒกๆ็ ไบใไธ่ฌๅปบ่ฎฎ้ข็10-20%็ไฝ้ใ
-- ่ฎก็ฎๆดปๅจๅ
ๆข็
SELECT
a.activity_id,
a.activity_name,
COUNT(DISTINCT gc.id) as total_codes,
COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) as redeemed_codes,
ROUND(COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) * 100.0 /
NULLIF(COUNT(DISTINCT gc.id), 0), 2) as redeem_rate_pct,
-- ๆๆๅ
ๆข็๏ผๅช่ฎก็ฎๆช่ฟๆใๆชๅๆถ็็ ๏ผ
COUNT(DISTINCT CASE WHEN gc.status = 1 AND gc.expire_time > NOW() THEN gc.id END) as valid_redeemed,
ROUND(COUNT(DISTINCT CASE WHEN gc.status = 1 AND gc.expire_time > NOW() THEN gc.id END) * 100.0 /
NULLIF(COUNT(DISTINCT CASE WHEN gc.expire_time > NOW() AND gc.cancelled_at IS NULL THEN gc.id END), 0), 2)
as valid_redeem_rate_pct
FROM activity a
LEFT JOIN gift_code gc ON a.id = gc.activity_id
WHERE a.start_time >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY a.activity_id, a.activity_name
ORDER BY redeem_rate_pct DESC;
10000ไธช็ ๏ผๆฏ1ๅฐๆถๅ ่ขซๆขๅ ๏ผ่ฟๆฏ1ไธชๆ้ฝๆฒกๅๅฎ๏ผๅ ๆข้ๅบฆๅๆ ไบๆดปๅจ็็ญๅบฆๅ็ดง่ฟซๆใ
-- ่ฎก็ฎๅ
ๆข้ๅบฆๆๆ ๏ผT50/T90/T99๏ผ
WITH redeem_timeline AS (
SELECT
gc.activity_id,
gc.id as code_id,
r.redeem_time,
a.start_time as activity_start,
ROW_NUMBER() OVER (PARTITION BY gc.activity_id ORDER BY r.redeem_time) as redeem_rank,
COUNT(*) OVER (PARTITION BY gc.activity_id) as total_redeemed
FROM gift_code gc
INNER JOIN gift_code_redeem_log r ON gc.id = r.code_id AND r.status = 1
INNER JOIN activity a ON gc.activity_id = a.id
WHERE gc.status = 1
),
percentiles AS (
SELECT
activity_id,
MIN(redeem_time) as first_redeem,
MAX(redeem_time) as last_redeem,
MAX(CASE WHEN redeem_rank <= total_redeemed * 0.5 THEN redeem_time END) as t50_time,
MAX(CASE WHEN redeem_rank <= total_redeemed * 0.9 THEN redeem_time END) as t90_time,
MAX(CASE WHEN redeem_rank <= total_redeemed * 0.99 THEN redeem_time END) as t99_time,
MAX(activity_start) as activity_start,
MAX(total_redeemed) as total_redeemed
FROM redeem_timeline
GROUP BY activity_id
)
SELECT
activity_id,
total_redeemed,
TIMESTAMPDIFF(MINUTE, activity_start, first_redeem) as minutes_to_first,
TIMESTAMPDIFF(MINUTE, activity_start, t50_time) as minutes_to_t50,
TIMESTAMPDIFF(MINUTE, activity_start, t90_time) as minutes_to_t90,
TIMESTAMPDIFF(MINUTE, activity_start, t99_time) as minutes_to_t99,
TIMESTAMPDIFF(HOUR, activity_start, last_redeem) as hours_total
FROM percentiles
ORDER BY total_redeemed DESC;
่ฟไธชๆๆ ๅธฎๅฉ่ฏไผฐ็ณป็ป็ๆฟ่ฝฝ่ฝๅใๅฆๆๅณฐๅผๅ ๆข้่ฟ่ถ ็ณป็ป่ฎพ่ฎกๅฎน้๏ผไธๆฌกๆดปๅจๅๅฐฑ้่ฆๆฉๅฎนใ
-- ่ฎก็ฎไธๅๆถ้ด็ฒๅบฆ็ๅณฐๅผๅ
ๆข้
SELECT
activity_id,
redeem_date,
-- ๅ้็บงๅณฐๅผ
MAX(minute_redeems) as peak_minute_redeems,
-- ๅฐๆถ็บงๅณฐๅผ
MAX(hour_redeems) as peak_hour_redeems,
-- ๅณฐๅผๅ็ๆถ้ด
SUBSTRING_INDEX(GROUP_CONCAT(peak_minute ORDER BY minute_redeems DESC), ',', 1) as peak_minute_time,
SUBSTRING_INDEX(GROUP_CONCAT(peak_hour ORDER BY hour_redeems DESC), ',', 1) as peak_hour_time
FROM (
SELECT
activity_id,
DATE(redeem_time) as redeem_date,
DATE_FORMAT(redeem_time, '%Y-%m-%d %H:%i') as minute_key,
DATE_FORMAT(redeem_time, '%Y-%m-%d %H') as hour_key,
COUNT(*) as minute_redeems,
0 as hour_redeems,
DATE_FORMAT(redeem_time, '%H:%i') as peak_minute,
'' as peak_hour
FROM dwd_gift_code_redeem_detail
WHERE status = 1
GROUP BY activity_id, DATE(redeem_time), DATE_FORMAT(redeem_time, '%Y-%m-%d %H:%i')
UNION ALL
SELECT
activity_id,
DATE(redeem_time) as redeem_date,
'' as minute_key,
DATE_FORMAT(redeem_time, '%Y-%m-%d %H') as hour_key,
0 as minute_redeems,
COUNT(*) as hour_redeems,
'' as peak_minute,
DATE_FORMAT(redeem_time, '%H') as peak_hour
FROM dwd_gift_code_redeem_detail
WHERE status = 1
GROUP BY activity_id, DATE(redeem_time), DATE_FORMAT(redeem_time, '%Y-%m-%d %H')
) t
GROUP BY activity_id, redeem_date
ORDER BY peak_minute_redeems DESC;
3.2 ็จๆท็ฑปๆๆ
ไธไธช็จๆทๅ ๆข10ๆฌก๏ผๅ10ไธช็จๆทๅๅ ๆข1ๆฌก๏ผๆไนๅฎๅ จไธๅใๅ่ ๅฏ่ฝๆฏๅท็ ๏ผๅ่ ๆๆฏ็ๆญฃ็็จๆท่งฆ่พพใ
-- ็จๆทๅ
ๆข่กไธบๅๆ
SELECT
activity_id,
activity_name,
-- ็จๆท็ป่ฎก
COUNT(DISTINCT user_id) as unique_users,
COUNT(*) as total_redeems,
ROUND(COUNT(*) * 1.0 / COUNT(DISTINCT user_id), 2) as avg_redeems_per_user,
-- ๆฐ่็จๆทๅๅธ
COUNT(DISTINCT CASE WHEN is_new_user = 1 THEN user_id END) as new_users,
COUNT(DISTINCT CASE WHEN is_new_user = 0 THEN user_id END) as old_users,
ROUND(COUNT(DISTINCT CASE WHEN is_new_user = 1 THEN user_id END) * 100.0 /
COUNT(DISTINCT user_id), 2) as new_user_ratio,
-- ๅ
ๆขๆฌกๆฐๅๅธ
COUNT(CASE WHEN redeem_cnt = 1 THEN 1 END) as single_redeem_users,
COUNT(CASE WHEN redeem_cnt BETWEEN 2 AND 5 THEN 1 END) as normal_multi_users,
COUNT(CASE WHEN redeem_cnt > 5 THEN 1 END) as heavy_users
FROM (
SELECT
d.activity_id,
d.activity_name,
d.user_id,
d.is_new_user,
COUNT(*) as redeem_cnt
FROM dwd_gift_code_redeem_detail d
WHERE d.status = 1
AND d.redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY d.activity_id, d.activity_name, d.user_id, d.is_new_user
) user_redeems
GROUP BY activity_id, activity_name
ORDER BY unique_users DESC;
็จๆทๅ ๆขไบ็คผๅ ๏ผ็ถๅๅข๏ผๆฏๆฟไบๅฅๅฑๅฐฑ่ท๏ผ่ฟๆฏ็ไธๆฅ็ปง็ปญ็ฉ๏ผ่ฟไธชๆๆ ่กก้็ๆฏๆดปๅจ็้ฟๆไปทๅผใ
-- ็จๆท็ๅญๅๆ๏ผๅ
ๆขๅ7/14/30ๅคฉ็ๅญ๏ผ
WITH redeem_users AS (
SELECT DISTINCT
user_id,
MIN(redeem_date) as first_redeem_date
FROM dwd_gift_code_redeem_detail
WHERE status = 1
AND redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 60 DAY)
GROUP BY user_id
),
retention_check AS (
SELECT
r.user_id,
r.first_redeem_date,
-- ๆฃๆฅ็จๆทๅจๅ็ๅญๆฅๆฏๅฆๆดป่ท
MAX(CASE WHEN DATE_ADD(r.first_redeem_date, INTERVAL 1 DAY) = u.active_date THEN 1 END) as day1_active,
MAX(CASE WHEN DATE_ADD(r.first_redeem_date, INTERVAL 7 DAY) = u.active_date THEN 1 END) as day7_active,
MAX(CASE WHEN DATE_ADD(r.first_redeem_date, INTERVAL 14 DAY) = u.active_date THEN 1 END) as day14_active,
MAX(CASE WHEN DATE_ADD(r.first_redeem_date, INTERVAL 30 DAY) = u.active_date THEN 1 END) as day30_active
FROM redeem_users r
LEFT JOIN user_daily_active u ON r.user_id = u.user_id
WHERE u.active_date BETWEEN r.first_redeem_date AND DATE_ADD(r.first_redeem_date, INTERVAL 30 DAY)
GROUP BY r.user_id, r.first_redeem_date
)
SELECT
first_redeem_date,
COUNT(*) as total_users,
SUM(IFNULL(day1_active, 0)) as day1_retained,
SUM(IFNULL(day7_active, 0)) as day7_retained,
SUM(IFNULL(day14_active, 0)) as day14_retained,
SUM(IFNULL(day30_active, 0)) as day30_retained,
ROUND(SUM(IFNULL(day1_active, 0)) * 100.0 / COUNT(*), 2) as day1_retention_pct,
ROUND(SUM(IFNULL(day7_active, 0)) * 100.0 / COUNT(*), 2) as day7_retention_pct,
ROUND(SUM(IFNULL(day14_active, 0)) * 100.0 / COUNT(*), 2) as day14_retention_pct,
ROUND(SUM(IFNULL(day30_active, 0)) * 100.0 / COUNT(*), 2) as day30_retention_pct
FROM retention_check
GROUP BY first_redeem_date
ORDER BY first_redeem_date DESC;
3.3 ๆธ ้็ฑปๆๆ
ไธๅๆธ ้็็จๆท่ดจ้ๅทฎๅผๅพๅคงใ้่ฟๅฏนๆฏๅๆธ ้็ๅ ๆข็ใROIๅ็ๅญ๏ผๅฏไปฅไผๅๆๆพ็ญ็ฅใ
-- ๆธ ้็ปผๅๆๆๅๆ
SELECT
c.channel_id,
c.channel_name,
c.channel_type,
-- ๆๆพ็ป่ฎก
COUNT(DISTINCT gc.id) as total_codes,
SUM(gc.cost) as total_cost,
-- ๅ
ๆข็ป่ฎก
COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) as redeemed_codes,
ROUND(COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) * 100.0 /
NULLIF(COUNT(DISTINCT gc.id), 0), 2) as redeem_rate,
-- ็จๆท็ป่ฎก
COUNT(DISTINCT r.user_id) as unique_users,
COUNT(DISTINCT CASE WHEN d.is_new_user = 1 THEN r.user_id END) as new_users,
ROUND(COUNT(DISTINCT CASE WHEN d.is_new_user = 1 THEN r.user_id END) * 100.0 /
NULLIF(COUNT(DISTINCT r.user_id), 0), 2) as new_user_ratio,
-- ไป่ดน็ป่ฎก๏ผ7ๆฅๅ
๏ผ
COUNT(DISTINCT CASE WHEN p.pay_time IS NOT NULL THEN r.user_id END) as pay_users,
SUM(IFNULL(p.pay_amount, 0)) as total_revenue,
ROUND(SUM(IFNULL(p.pay_amount, 0)) / NULLIF(SUM(gc.cost), 0), 2) as roi_7d,
-- ็จๆท่ดจ้ๆๆ
ROUND(AVG(d.user_level), 1) as avg_user_level,
ROUND(AVG(d.user_total_recharge), 2) as avg_ltv
FROM channel c
LEFT JOIN gift_code gc ON c.channel_id = gc.channel_id
LEFT JOIN gift_code_redeem_log r ON gc.id = r.code_id AND r.status = 1
LEFT JOIN dwd_gift_code_redeem_detail d ON r.id = d.redeem_id
LEFT JOIN (
SELECT user_id, MIN(pay_time) as pay_time, SUM(amount) as pay_amount
FROM user_payment
WHERE pay_time <= DATE_ADD(redeem_time, INTERVAL 7 DAY)
GROUP BY user_id
) p ON r.user_id = p.user_id
WHERE gc.created_at >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY c.channel_id, c.channel_name, c.channel_type
ORDER BY roi_7d DESC;
3.4 ๆถ้ด็ฑปๆๆ
็ฉๅฎถไปไนๆถๅๆๆดป่ท๏ผไปไนๆถๅๆๅฎนๆ็ๅฐๆจ้๏ผ่ฟไธชๆๆ ๅธฎๅฉไผๅๆๆพๅๆจ้ๆถๆบใ
-- ๅ
ๆขๆถๆฎต็ญๅๅพๆฐๆฎ๏ผๅฐๆถ x ๆๆ๏ผ
SELECT
day_of_week,
redeem_hour,
COUNT(*) as redeem_count,
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER(), 4) as percentage,
-- ไธๅนณๅๅผๆฏ่พ
ROUND(COUNT(*) * 1.0 / AVG(COUNT(*)) OVER(), 2) as index_vs_avg
FROM dwd_gift_code_redeem_detail
WHERE status = 1
AND redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY day_of_week, redeem_hour
ORDER BY day_of_week, redeem_hour;
-- ็ๆ็ญๅๅพๆฐๆฎๆ ผๅผ๏ผๅฏ็ดๆฅ็จไบๅ็ซฏๅฑ็คบ๏ผ
SELECT
CONCAT('[', GROUP_CONCAT(
CONCAT('{x:', redeem_hour, ',y:', day_of_week - 1, ',value:', redeem_count, '}')
ORDER BY day_of_week, redeem_hour
), ']') as heatmap_data
FROM (
SELECT day_of_week, redeem_hour, COUNT(*) as redeem_count
FROM dwd_gift_code_redeem_detail
WHERE status = 1 AND redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY day_of_week, redeem_hour
) t;
3.5 ๅฅๅฑ็ฑปๆๆ
ๅช็งๅฅๅฑๆๅๆฌข่ฟ๏ผๅช็งๅฅๅฑๅ ๆขๅ็จๆทๆปกๆๅบฆๆ้ซ๏ผๅช็งๅฅๅฑๅฏน็ๅญ็่ดก็ฎๆๅคง๏ผ
-- ๅฅๅฑๆๆ็ปผๅๅๆ
SELECT
reward_id,
reward_name,
reward_type,
reward_value,
-- ็ญๅบฆๆๆ
COUNT(*) as redeem_count,
COUNT(DISTINCT user_id) as unique_users,
RANK() OVER (ORDER BY COUNT(*) DESC) as popularity_rank,
-- ๆปกๆๅบฆไปฃ็ๆๆ ๏ผๅ
ๆขๅ7ๆฅๆดป่ทๅคฉๆฐ๏ผ
ROUND(AVG(active_days_7d), 1) as avg_active_days_7d,
-- ไป่ดน่ฝฌๅ
COUNT(DISTINCT CASE WHEN has_paid_7d = 1 THEN user_id END) as pay_convert_users,
ROUND(COUNT(DISTINCT CASE WHEN has_paid_7d = 1 THEN user_id END) * 100.0 /
NULLIF(COUNT(DISTINCT user_id), 0), 2) as pay_convert_rate,
-- ็ๅญ่ดก็ฎ
ROUND(AVG(day7_retention) * 100, 2) as avg_day7_retention_pct,
-- ROI
ROUND(SUM(total_pay_7d) / NULLIF(reward_value * COUNT(*), 0), 2) as roi
FROM (
SELECT
d.reward_id,
d.reward_name,
d.reward_type,
d.reward_value,
d.user_id,
COUNT(DISTINCT u.active_date) as active_days_7d,
MAX(CASE WHEN p.pay_time IS NOT NULL THEN 1 ELSE 0 END) as has_paid_7d,
SUM(IFNULL(p.amount, 0)) as total_pay_7d,
MAX(CASE WHEN u.active_date = DATE_ADD(d.redeem_date, INTERVAL 7 DAY) THEN 1 ELSE 0 END) as day7_retention
FROM dwd_gift_code_redeem_detail d
LEFT JOIN user_daily_active u ON d.user_id = u.user_id
AND u.active_date BETWEEN d.redeem_date AND DATE_ADD(d.redeem_date, INTERVAL 7 DAY)
LEFT JOIN user_payment p ON d.user_id = p.user_id
AND p.pay_time BETWEEN d.redeem_time AND DATE_ADD(d.redeem_time, INTERVAL 7 DAY)
WHERE d.status = 1
AND d.redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY d.reward_id, d.reward_name, d.reward_type, d.reward_value, d.user_id
) reward_user
GROUP BY reward_id, reward_name, reward_type, reward_value
ORDER BY redeem_count DESC;
ๅใๆฅ่กจ็ณป็ป่ฎพ่ฎก
ๆๆ ๆไบ๏ผๆฅไธๆฅๆฏๅฆไฝๅ็ฐใๅฅฝ็ๆฅ่กจ็ณป็ป๏ผ่ฆๅไธไฝไผ็ง็ๅๆๅธโโไธไป ๅฑ็คบๆฐๆฎ๏ผ่ฟ่ฆ่ฎฒๆธ ๆฅๆฐๆฎ่ๅ็ๆ ไบใ
4.1 ๆฅ่กจๅๅฑๆถๆ
ๆฅ่กจ็ณป็ปๅบ่ฏฅๅๆด่ฑไธๆ ท๏ผไธๅฑไธๅฑๅฅๅผ๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ็ฌฌไธๅฑ๏ผๆฆ่งๅคงๅฑ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โไปๆฅๅ
ๆข้โ โๅ
ๆข็ โ โๆดป่ทๆดปๅจ โ โๅผๅธธ้ข่ญฆ โ โ
โ โ12,345 โ โ67.8% โ โ15ไธช โ โ2ไธช โ โ
โ โโ 15% โ โโ 3.2% โ โโ 3ไธช โ โโ ๏ธ โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ่ถๅฟๅพ่กจ๏ผๆ็บฟๅพ๏ผ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ็ฌฌไบๅฑ๏ผ็ปดๅบฆๅๆ โ
โ โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๆธ ้ๅๆ โ โ ๆถ้ดๅๆ โ โ
โ โ (ๆฑ็ถๅพ/ๆกๅฝขๅพ) โ โ (็ญๅๅพ/ๆฅๅๅพ) โ โ
โ โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๅฅๅฑๅๆ โ โ ็จๆทๅๆ โ โ
โ โ (้ฅผๅพ/็ฏๅฝขๅพ) โ โ (ๆผๆๅพ/้ท่พพๅพ) โ โ
โ โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ ็ฌฌไธๅฑ๏ผๆ็ปๆฅ่ฏข โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ็ญ้ๆกไปถ๏ผ[ๆดปๅจ] [ๆธ ้] [ๆถ้ด] [ๅฅๅฑ] [ๆดๅค โผ] โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ ็จๆทID โๅ
ๆขๆถ้ดโๅฅๅฑโๆธ ้โ็ถๆโๆไฝ โ โ
โ โ 10001 โ02-28 15:30โ้ป้็คผๅ
โๅพฎไฟกโๆๅโ[่ฏฆๆ
] โ โ
โ โ 10002 โ02-28 15:29โ็ฝ้ถ็คผๅ
โๆ้ณโๆๅโ[่ฏฆๆ
] โ โ
โ โ ... โ... โ... โ... โ... โ... โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ [ๅฏผๅบCSV] [ๅฏผๅบExcel] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่ฟ่ฅ่ด่ดฃไบบๆๅผๆฅ่กจ๏ผ็ฌฌไธ็ผ็ๅฐ็ๆฏไปไน๏ผ
- ไปๆฅ/ๆฌๅจ/ๆฌๆ็ๆปๅ ๆข้
- ๆ ธๅฟๆๆ ็ๅๆฏ/็ฏๆฏๅๅ
- ๅผๅธธ้ข่ญฆ๏ผๅ ๆข็ๅผๅธธใๅณฐๅผๅผๅธธ็ญ๏ผ
่ฟไธๅฑๅ็ญ็้ฎ้ขๆฏ๏ผๆดไฝๆ ๅตๅฆไฝ๏ผๆๆฒกๆ้่ฆ็ซๅณๅ ณๆณจ็้ฎ้ข๏ผ
ไปๆฆ่งๅ็ฐๅผๅธธๅ๏ผ้่ฆไธ้ปๅๆใๆฏๆๅค็ปดๅบฆไบคๅๅๆ๏ผๆฏๅฆ"ๆฐ็จๆทๅจๅจๆซๅฏนๅๅฅๅฑ็ฑปๅ็ๅๅฅฝ"ใ
้่ฆ็ๅฐๅ ทไฝ็ๆฐๆฎๆถ๏ผๆฏๆ็ตๆดป็ญ้ๅๆฐๆฎๅฏผๅบใ
4.2 ๅฏ่งๅๅพ่กจ่ฎพ่ฎก
ไธๅ็ๆฐๆฎ๏ผ้ๅไธๅ็ๅพ่กจใ้้ๅพ่กจ็ฑปๅ๏ผไผ่ฎฉๆฐๆฎๅๅพ้พไปฅ็่งฃใ้ๆฉๆญฃ็กฎ็ๅพ่กจ็ฑปๅ๏ผ่ฝ่ฎฉๆฐๆฎ่ชๅทฑ่ฏด่ฏใ
| ๅๆ็ฎ็ | ๆจ่ๅพ่กจ | ้็จๅบๆฏ | ็คบไพ |
|---|---|---|---|
| ็่ถๅฟ | ๆ็บฟๅพใ้ข็งฏๅพ | ๅ ๆข้้ๆถ้ดๅๅ | ๆฅๅ ๆข้่ถๅฟ |
| ็ๅ ๆฏ | ้ฅผๅพใ็ฏๅฝขๅพใๆ ๅพ | ๅๆธ ้ๅ ๆขๅ ๆฏ | ๆธ ้ๅๅธ |
| ็ๅฏนๆฏ | ๆฑ็ถๅพใๆกๅฝขๅพ | ไธๅๆดปๅจๆๆๅฏนๆฏ | ๆดปๅจๅ ๆข็ๆๅ |
| ็ๅๅธ | ็ดๆนๅพใ็ฎฑ็บฟๅพ | ็จๆทๅ ๆขๆฌกๆฐๅๅธ | ไบบๅๅ ๆขๅๅธ |
| ็ๅ ณ็ณป | ๆฃ็นๅพใๆฐๆณกๅพ | ๅ ๆข็ๅ็ๅญ็ๅ ณ็ณป | ROI vs ็ๅญๆฃ็น |
| ็ๅฏๅบฆ | ็ญๅๅพ | ๆถๆฎตๆดป่ทๅๅธ | ๅ ๆขๆถๆฎต็ญๅๅพ |
| ็ๆต็จ | ๆผๆๅพใๆกๅบๅพ | ็จๆท่ฝฌๅ่ทฏๅพ | ไปๆๅ ๅฐๅ ๆข |
4.2.1 ่ถๅฟๆ็บฟๅพ๏ผๅธฆ้ข่ญฆ็บฟ๏ผ
ๅ
ๆข้่ถๅฟๅพ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1500 โค โญโโโโฎ โ
โ โ โญโฏ โฒ โ
โ 1200 โค โญโโโโฏ โฒ โญโโโฎ โ
โ โ โญโโโโฏ โฒโโฏ โฒ โ
โ 900 โค โญโโโโฎโฏ โฒ โ
โ โ โญโโโโฏ โฒ โฒโโโฎ โ
โ 600 โคโโโโฏ โฒ โฒโโ
โ โ โฒ โ
โ 300 โค โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โโ โ ้ข่ญฆ็บฟ
โ โ โฒโ
โ 0 โผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ 02-22 02-23 02-24 02-25 02-26 02-27 02-28โ
โ โ
โ โโโ ไปๆฅ โโโ ๆจๆฅ โฒ ๅณฐๅผ โ ๅผๅธธ็น โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่ฎพ่ฎก่ฆ็น๏ผ
- ๆพ็คบๅฝๅๆฐๆฎๅๅๅฒๅฏนๆฏ
- ๆ ๆณจๅณฐๅผๅๅผๅธธ็น
- ๆทปๅ ้ข่ญฆ็บฟ๏ผ้ๅผ๏ผ
- ้ผ ๆ ๆฌๅๆพ็คบๅ ทไฝๆฐๅผ
4.2.2 ๆธ ้ๅฏนๆฏๆฑ็ถๅพ
ๆธ ้ๆๆๅฏนๆฏ๏ผๆๅ
ๆข็ๆๅบ๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ ๅพฎไฟกๅฐ็จๅบ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 89.2% โ
โ ๆ้ณ โโโโโโโโโโโโโโโโโโโโโโโโโโ 76.5% โ
โ B็ซ โโโโโโโโโโโโโโโโโโโโ 65.3% โ
โ ๅพฎๅ โโโโโโโโโโโโโโโโ 52.1% โ
โ ๅฐ็บขไนฆ โโโโโโโโโโโโ 43.8% โ
โ QQ โโโโโโโโ 31.2% โ
โ ๅฎ็ฝ โโโโ 18.5% โ
โ โ
โ โโโ ๅ
ๆข็ โโโ ้ข่ญฆ้ๅผ(40%) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่ฎพ่ฎก่ฆ็น๏ผ
- ๆๆฐๅผๅคงๅฐๆๅบ๏ผไธ็ฎไบ็ถ
- ็จ้ข่ฒๅบๅ่พพๆ /ๆช่พพๆ
- ๆฏๆ็นๅปไธ้ปๆฅ็่ฏฆๆ
4.2.3 ๆถๆฎต็ญๅๅพ
ๅ
ๆขๆถๆฎต็ญๅๅพ๏ผ้ข่ฒ่ถๆทฑ = ๅ
ๆข่ถๆดป่ท๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 0 2 4 6 8 10 12 14 16 18 20 22 โ
โ ๅจไธ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ ๅจไบ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ ๅจไธ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ ๅจๅ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ ๅจไบ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ ๅจๅ
ญ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ ๅจๆฅ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ โ
โ โ ไฝๆดป่ท โ ไธญ็ญ โ ้ซๆดป่ท โ ๅณฐๅผ โ
โ โ
โ ๐ก ๆไฝณๆจ้ๆถๆฎต๏ผๅจๆซ 14:00-20:00 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่ฎพ่ฎก่ฆ็น๏ผ
- ็จ้ข่ฒๆทฑๆต ่กจ็คบๆดป่ท็จๅบฆ
- ๆ ๆณจๆไฝณๆถๆฎตๅปบ่ฎฎ
- ๆฏๆๆๆดปๅจ/ๆธ ้็ญ้
4.2.4 ็จๆท่ฝฌๅๆผๆ
็จๆท่ฝฌๅๆผๆๅๆ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ ๆดปๅจๆๅ
100,000 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ 45% โ
โ ็นๅป่ฟๅ
ฅ 45,000 โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 62% โ
โ ่ทๅ็คผๅ
็ 27,900 โโโโโโโโโโโโโโโโโโโโ โ
โ โ 78% โ
โ ๆๅผๆธธๆ 21,762 โโโโโโโโโโโโโโโโ โ
โ โ 85% โ
โ ๆๅๅ
ๆข 18,498 โโโโโโโโโโโโโโ โ
โ โ 72% โ
โ 7ๆฅ็ๅญ 13,318 โโโโโโโโโโโโ โ
โ โ
โ ๆดไฝ่ฝฌๅ็๏ผ18.5% ๅ
ณ้ฎๆตๅคฑ็น๏ผ็นๅปโ่ทๅ็ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
่ฎพ่ฎก่ฆ็น๏ผ
- ๆธ ๆฐๅฑ็คบๆฏๆญฅ่ฝฌๅ็
- ๆ ๆณจๅ ณ้ฎๆตๅคฑ็น
- ๆฏๆๅฏนๆฏไธๅๆดปๅจ/ๆธ ้
4.3 ๅฎๆถ vs ็ฆป็บฟๆฅ่กจ
-- ๅฎๆถ็ๆงSQL็คบไพ๏ผClickHouse๏ผ
SELECT
'current_redeem_count' as metric,
COUNT(*) as value,
'ๆฌก' as unit,
(SELECT COUNT(*) FROM gift_code_redeem_log
WHERE redeem_time >= DATE_SUB(NOW(), INTERVAL 1 DAY)) as compare_value,
ROUND((COUNT(*) - compare_value) * 100.0 / NULLIF(compare_value, 0), 2) as change_rate
FROM gift_code_redeem_log
WHERE redeem_time >= toStartOfMinute(NOW() - INTERVAL 5 MINUTE);
-- ๅฎๆถๅผๅธธๆฃๆต
SELECT
activity_id,
DATE_FORMAT(redeem_time, '%Y-%m-%d %H:%i') as minute,
COUNT(*) as redeem_count,
CASE
WHEN COUNT(*) > 1000 THEN 'ALERT' -- ่ถ
่ฟ1000ๆฌก/ๅ้ๅ่ญฆ
WHEN COUNT(*) > 500 THEN 'WARNING' -- ่ถ
่ฟ500ๆฌก/ๅ้้ข่ญฆ
ELSE 'NORMAL'
END as status
FROM gift_code_redeem_log
WHERE redeem_time >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)
GROUP BY activity_id, DATE_FORMAT(redeem_time, '%Y-%m-%d %H:%i')
HAVING status != 'NORMAL';
็ฆป็บฟๆฅ่กจๅฏไปฅๅๆดๅคๆ็่ฎก็ฎ๏ผๆฏๅฆ็จๆท็ๅญๅๆใLTV่ฎก็ฎใๅฝๅ ๅๆ็ญใ
4.4 ๆฅ่กจๆง่ฝไผๅ
ๅฝๆฐๆฎ้่พพๅฐๅไธ็บง็่ณไบฟ็บงๆถ๏ผๆฅ่กจๆฅ่ฏขๆง่ฝๅฐฑๆไบๅ ณ้ฎ้ฎ้ขใ
ๆ็ปๅธธๆฅ่ฏข็ๆๆ ้ขๅ ่ฎก็ฎๅฅฝ๏ผๅญๅ ฅๆฑๆป่กจใ
-- ๆฏๆฅๅๆจๆง่ก้ข่ๅ
INSERT INTO dws_activity_daily_summary
SELECT
activity_id,
CURRENT_DATE - INTERVAL 1 DAY as stat_date,
-- ... ๅ็ง่ๅๆๆ
FROM dwd_gift_code_redeem_detail
WHERE redeem_date = CURRENT_DATE - INTERVAL 1 DAY
GROUP BY activity_id;
ๆๆฅๆๅๅบ๏ผๆฅ่ฏขๆถๅชๆซๆ้่ฆ็ๅๅบใ
-- ๅๅปบๅๅบ่กจ
CREATE TABLE dwd_gift_code_redeem_detail (
-- ๅญๆฎตๅฎไน...
) PARTITION BY RANGE (TO_DAYS(redeem_date)) (
PARTITION p202601 VALUES LESS THAN (TO_DAYS('2026-02-01')),
PARTITION p202602 VALUES LESS THAN (TO_DAYS('2026-03-01')),
PARTITION p202603 VALUES LESS THAN (TO_DAYS('2026-04-01')),
-- ...
);
-- ๆฅ่ฏขๆถ่ชๅจๅฉ็จๅๅบ่ฃๅช
SELECT * FROM dwd_gift_code_redeem_detail
WHERE redeem_date >= '2026-02-01' AND redeem_date < '2026-03-01';
-- ๅชไผๆซๆ p202602 ๅๅบ
ๅฏนไบๅคๆ็ๅๆๆฅ่ฏข๏ผๅฏไปฅๅๅปบ็ฉๅ่งๅพใ
-- ๅๅปบ็ฉๅ่งๅพ๏ผ่ชๅจๅทๆฐ๏ผ
CREATE MATERIALIZED VIEW mv_channel_daily_stats
REFRESH FAST ON DEMAND
AS SELECT
channel_id,
redeem_date,
COUNT(*) as redeem_count,
COUNT(DISTINCT user_id) as unique_users,
-- ... ๅ
ถไปๆๆ
FROM dwd_gift_code_redeem_detail
GROUP BY channel_id, redeem_date;
ๅฏนไบ้ซ้ขๆฅ่ฏข็็ปๆ๏ผๅฏไปฅ็ผๅญ่ตทๆฅใ
ๆฅ่ฏข่ฏทๆฑ โ Redis็ผๅญ โ ๅฝไธญ๏ผโ ่ฟๅ็ปๆ
โ ๆชๅฝไธญ
ๆฐๆฎๅบๆฅ่ฏข โ ๅๅ
ฅ็ผๅญ โ ่ฟๅ็ปๆ
็ผๅญ็ญ็ฅ๏ผ
- ็ญ็นๆฐๆฎ๏ผTTL 5ๅ้
- ๅๅฒๆฐๆฎ๏ผTTL 24ๅฐๆถ
- ๅฎๆถๆฐๆฎ๏ผไธ็ผๅญๆ TTL 30็ง
ไบใๆฐๆฎๅๆๆนๆณ่ฎบ
ๆไบๆฐๆฎๅๆฅ่กจ๏ผๆฅไธๆฅๆฏๅฆไฝๅๆใๅๆไธๆฏ็ฎๅ็"็ๆฐๆฎ"๏ผ่ๆฏ่ฆๆๆนๆณใๆ้ป่พใๆ็ป่ฎบใ
5.1 ่ถๅฟๅๆๆณ
ไปๅคฉ็ๅ ๆข้ๆฏ5000๏ผ่ฟไธชๆฐๅญๆฌ่บซๆฒกๆๆไนใไธๅจไบๆฏ4000๏ผไธไธๅจๆฏ3000โโๅข้ฟ่ถๅฟๅพๆๆพใ
- ็กฎๅฎๅบๅ็บฟ๏ผ้ๆฉๅ้็ๅฏนๆฏๅจๆ๏ผ็ฏๆฏ/ๅๆฏ/็ฎๆ ๏ผ
- ่ฏๅซ่ถๅฟๆนๅ๏ผไธๅ/ไธ้/ๆๅนณ
- ๅคๆญ่ถๅฟๅผบๅบฆ๏ผ็ผๆ ข/ไธญ็ญ/ๅง็
- ้ขๆตๆชๆฅ่ตฐๅ๏ผๅบไบๅๅฒ่งๅพ
-- ่ถๅฟๅๆSQL๏ผ่ฎก็ฎ็งปๅจๅนณๅๅ่ถๅฟ
WITH daily_stats AS (
SELECT
redeem_date,
COUNT(*) as daily_redeems
FROM dwd_gift_code_redeem_detail
WHERE redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY redeem_date
),
with_ma AS (
SELECT
redeem_date,
daily_redeems,
-- 7ๆฅ็งปๅจๅนณๅ
AVG(daily_redeems) OVER (
ORDER BY redeem_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as ma_7d,
-- ็ฏๆฏๅๅ
LAG(daily_redeems) OVER (ORDER BY redeem_date) as prev_day,
-- ๅๆฏๅๅ
LAG(daily_redeems, 7) OVER (ORDER BY redeem_date) as prev_week
FROM daily_stats
)
SELECT
redeem_date,
daily_redeems,
ma_7d,
ROUND(ma_7d - LAG(ma_7d) OVER (ORDER BY redeem_date), 2) as ma_trend,
ROUND((daily_redeems - prev_day) * 100.0 / NULLIF(prev_day, 0), 2) as dod_change,
ROUND((daily_redeems - prev_week) * 100.0 / NULLIF(prev_week, 0), 2) as wow_change,
CASE
WHEN daily_redeems > ma_7d * 1.2 THEN 'ABOVE_NORMAL'
WHEN daily_redeems < ma_7d * 0.8 THEN 'BELOW_NORMAL'
ELSE 'NORMAL'
END as status
FROM with_ma
ORDER BY redeem_date DESC;
ๅ
ๆข้่ถๅฟๅๆ๏ผๅซ็งปๅจๅนณๅ๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2000 โค โญโโโฎ โ
โ โ ยท ยท โญโโโฏ โฒ ยท โ
โ 1500 โค ยท ยท โญโโโโฏ โฒโโโฎ ยท ยท โ
โ โยท โฑ โฒ ยท โ
โ 1000 โคโโโโโโโโโโโฑโโโโโโโโโโโโโโโโโโฒโโโโโโโโโโโโโยทโโโโ โ 7ๆฅMA
โ โ ยท ยท ยท ยท ยท โฒ ยท ยท โ
โ 500 โค โฒ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฒโโโโโโโโโโโโโโโ
โ 02-01 02-05 02-10 02-15 02-20 02-25 02-28 โ
โ โ
โ ยท ๆฅๅ
ๆข้ โโโ 7ๆฅ็งปๅจๅนณๅ โ
โ โ
โ ๐ ๅๆ็ป่ฎบ๏ผ โ
โ โข ๆดไฝๅไธๅ่ถๅฟ๏ผ7ๆฅMAไป800ๅ่ณ1200 (+50%) โ
โ โข 02-15ๅบ็ฐๅผๅธธๅณฐๅผ๏ผ้ๅ
ณๆณจๅๅ โ
โ โข ่ฟ3ๆฅ็จณๅฎๅจMA้่ฟ๏ผ่ถๅฟๅฅๅบท โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
5.2 ๅฝๅ ๅๆๆณ
ๆฐๆฎๅผๅธธไบ๏ผๆไนๆพๅๅ ๏ผ้่ฟ็ปดๅบฆไธ้ปๅ็ธๅ ณๆงๅๆใ
โโโโโโโโโโโโโโโโโโโ
โ ๆปไฝๆๆ ๅๅ โ
โ (ๅฆๅ
ๆข็ไธ้) โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ
โ ๆธ ้็ปดๅบฆ โ โ ๆถ้ด็ปดๅบฆ โ โ ็จๆท็ปดๅบฆ โ
โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ
โ โ โ
โโโโโโผโโโโโ โโโโโโผโโโโโ โโโโโโผโโโโโ
โผ โผ โผ โผ โผ โผ โผ โผ โผ
ๅพฎไฟก ๆ้ณ ... ๅจๆซ ๅทฅไฝๆฅ ... ๆฐ็จๆท ่็จๆท ...
-- ๅฝๅ ๅๆ๏ผๆพๅฐๅ
ๆข็ไธ้็ๆ นๆฌๅๅ
WITH base_metrics AS (
-- ๅบๅๆ๏ผไธๅจ๏ผ
SELECT
channel_id,
'baseline' as period,
COUNT(DISTINCT gc.id) as total_codes,
COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) as redeemed,
ROUND(COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) * 100.0 /
NULLIF(COUNT(DISTINCT gc.id), 0), 2) as redeem_rate
FROM gift_code gc
WHERE gc.created_at BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 14 DAY)
AND DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
GROUP BY channel_id
UNION ALL
-- ๅฏนๆฏๆ๏ผๆฌๅจ๏ผ
SELECT
channel_id,
'current' as period,
COUNT(DISTINCT gc.id) as total_codes,
COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) as redeemed,
ROUND(COUNT(DISTINCT CASE WHEN gc.status = 1 THEN gc.id END) * 100.0 /
NULLIF(COUNT(DISTINCT gc.id), 0), 2) as redeem_rate
FROM gift_code gc
WHERE gc.created_at >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
GROUP BY channel_id
)
SELECT
c.channel_name,
MAX(CASE WHEN period = 'baseline' THEN redeem_rate END) as baseline_rate,
MAX(CASE WHEN period = 'current' THEN redeem_rate END) as current_rate,
MAX(CASE WHEN period = 'current' THEN redeem_rate END) -
MAX(CASE WHEN period = 'baseline' THEN redeem_rate END) as rate_change,
-- ่ดก็ฎๅบฆ่ฎก็ฎ
ROUND((MAX(CASE WHEN period = 'current' THEN redeemed END) -
MAX(CASE WHEN period = 'baseline' THEN redeemed END)) * 100.0 /
NULLIF((SELECT SUM(CASE WHEN period = 'current' THEN redeemed END) -
SUM(CASE WHEN period = 'baseline' THEN redeemed END)
FROM base_metrics WHERE period != 'total'), 0), 2) as contribution_pct
FROM base_metrics b
JOIN channel c ON b.channel_id = c.channel_id
GROUP BY c.channel_name
ORDER BY rate_change ASC;
๐ ๅ
ๆข็ไธ้ๅฝๅ ๅๆๆฅๅ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ ้ฎ้ขๆ่ฟฐ
โข ๆปไฝๅ
ๆข็ไป 68.5% ไธ้่ณ 52.3% (-16.2pp)
โข ๅฝฑๅ่ๅด๏ผๅ
จๆธ ้
โข ๆ็ปญๆถ้ด๏ผ่ฟ7ๅคฉ
๐ ๅฝๅ ๅๆ
ใๆธ ้็ปดๅบฆใ
โโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโ
โ ๆธ ้ โ ๅบๅๆ โ ๆฌๆ โ ๅๅ โ ่ดก็ฎๅบฆ โ
โโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโค
โ ๅพฎๅ โ 72.3% โ 31.2% โ -41.1ppโ 45.2% โ โ ไธป่ฆๅๅ
โ ๅฐ็บขไนฆ โ 58.6% โ 42.1% โ -16.5ppโ 28.3% โ
โ ๆ้ณ โ 81.2% โ 68.5% โ -12.7ppโ 18.5% โ
โ ๅพฎไฟก โ 65.4% โ 63.2% โ -2.2ppโ 8.0% โ
โโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโ
ใๆถ้ด็ปดๅบฆใ
โข ๅทฅไฝๆฅๅฝฑๅๆดๅคง๏ผ-18.3pp vs ๅจๆซ-8.6pp๏ผ
โข ๆ้ดๆถๆฎต๏ผ18:00-22:00๏ผไธ้ๆๆๆพ
๐ก ๆ นๅ ๅฎไฝ
1. ๅพฎๅๆธ ้ๆๆพ็ญ็ฅๅๆด๏ผๆฐๆฅๅ
ฅไบๅญๆธ ้X๏ผ
2. ๅญๆธ ้X็จๆท่ดจ้่พๅทฎ๏ผๅ
ๆข็ไป
15%
3. ๆไฝไบๅพฎๅๆดไฝๅ
ๆข็
โ
ๅปบ่ฎฎๆชๆฝ
1. ๆๅๅญๆธ ้Xๆๆพ
2. ๅพฎๅๆธ ้้ๆฐ่ฏไผฐROI
3. ๅปบ็ซๆธ ้ๅๅ
ฅๆบๅถ
5.3 ๆผๆๅๆๆณ
็จๆทไป็ๅฐๆดปๅจๅฐๆๅๅ ๆข๏ผ้่ฆ็ป่ฟๅคไธชๆญฅ้ชคใๆฏไธชๆญฅ้ชค้ฝๆๆตๅคฑ๏ผๆผๆๅๆๅธฎๅฉๆพๅบ้ฎ้ขๆๅคง็็ฏ่ใ
-- ๆผๆๅๆSQL
WITH funnel_steps AS (
SELECT
user_id,
-- ๆญฅ้ชค1๏ผๆดปๅจๆๅ
MAX(CASE WHEN event_type = 'activity_expose' THEN event_time END) as step1_time,
-- ๆญฅ้ชค2๏ผ็นๅป่ฟๅ
ฅ
MAX(CASE WHEN event_type = 'activity_click' THEN event_time END) as step2_time,
-- ๆญฅ้ชค3๏ผ่ทๅ็คผๅ
็
MAX(CASE WHEN event_type = 'get_code' THEN event_time END) as step3_time,
-- ๆญฅ้ชค4๏ผๆๅผๆธธๆ
MAX(CASE WHEN event_type = 'open_game' THEN event_time END) as step4_time,
-- ๆญฅ้ชค5๏ผๆๅๅ
ๆข
MAX(CASE WHEN event_type = 'redeem_success' THEN event_time END) as step5_time
FROM user_event_log
WHERE activity_id = 1001
AND event_date BETWEEN '2026-02-01' AND '2026-02-28'
GROUP BY user_id
)
SELECT
'ๆญฅ้ชค1: ๆดปๅจๆๅ
' as step_name,
COUNT(*) as user_count,
100.00 as conversion_rate,
0 as drop_rate
FROM funnel_steps WHERE step1_time IS NOT NULL
UNION ALL
SELECT
'ๆญฅ้ชค2: ็นๅป่ฟๅ
ฅ',
COUNT(*),
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM funnel_steps WHERE step1_time IS NOT NULL), 2),
ROUND(100 - COUNT(*) * 100.0 / (SELECT COUNT(*) FROM funnel_steps WHERE step1_time IS NOT NULL), 2)
FROM funnel_steps
WHERE step2_time IS NOT NULL
AND step2_time > step1_time
UNION ALL
SELECT
'ๆญฅ้ชค3: ่ทๅ็คผๅ
็ ',
COUNT(*),
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM funnel_steps WHERE step1_time IS NOT NULL), 2),
ROUND(100 - COUNT(*) * 100.0 / (SELECT COUNT(*) FROM funnel_steps WHERE step2_time IS NOT NULL), 2)
FROM funnel_steps
WHERE step3_time IS NOT NULL
AND step3_time > step2_time
-- ... ็ปง็ปญๅ
ถไปๆญฅ้ชค
;
| ๆตๅคฑ็ฏ่ | ๅฏ่ฝๅๅ | ไผๅๅปบ่ฎฎ |
|---|---|---|
| ๆๅ โ็นๅป | ๆดปๅจๅ ่ฃ ไธๅคๅธๅผ | ไผๅๆดปๅจๅพ็ใๆๆก |
| ็นๅปโ่ทๅ็ | ่ทๅๆต็จๅคชๅคๆ | ็ฎๅๆไฝๆญฅ้ชค |
| ่ทๅ็ โๆๅผๆธธๆ | ๆฒกๆๅผๅฏผ็จๆท | ๆทปๅ ไธ้ฎ่ทณ่ฝฌ |
| ๆๅผๆธธๆโๅ ๆข | ๆพไธๅฐๅ ๆขๅ ฅๅฃ | ๅ ๆขๅ ฅๅฃๅ็ฝฎใๅผน็ชๅผๅฏผ |
5.4 ๅๆ็พคๅๆ๏ผCohort Analysis๏ผ
ๆๅไธๆถๆ๏ผๅไธๅคฉ/ๅไธๅจ/ๅไธๆ๏ผๅผๅงไฝฟ็จไบงๅ็็จๆทๅไธบไธ็ป๏ผ่ฟฝ่ธชไปไปฌๅ็ปญ็่กไธบใ
-- ๅๆ็พค็ๅญๅๆSQL
WITH user_cohort AS (
-- ๆ็จๆท้ฆๆฌกๅ
ๆขๆฅๆๅ็ป
SELECT
user_id,
MIN(DATE(redeem_time)) as cohort_date
FROM dwd_gift_code_redeem_detail
WHERE status = 1
GROUP BY user_id
),
cohort_activity AS (
-- ่ฎก็ฎๆฏไธช็จๆทๅจๆฏไธชๆถๆฎต็ๆดป่ทๆ
ๅต
SELECT
c.cohort_date,
DATEDIFF(a.active_date, c.cohort_date) as days_since_first,
COUNT(DISTINCT c.user_id) as active_users
FROM user_cohort c
LEFT JOIN user_daily_active a ON c.user_id = a.user_id
WHERE c.cohort_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
GROUP BY c.cohort_date, DATEDIFF(a.active_date, c.cohort_date)
)
SELECT
cohort_date,
SUM(CASE WHEN days_since_first = 0 THEN active_users ELSE 0 END) as day0,
SUM(CASE WHEN days_since_first = 1 THEN active_users ELSE 0 END) as day1,
SUM(CASE WHEN days_since_first = 7 THEN active_users ELSE 0 END) as day7,
SUM(CASE WHEN days_since_first = 14 THEN active_users ELSE 0 END) as day14,
SUM(CASE WHEN days_since_first = 30 THEN active_users ELSE 0 END) as day30,
-- ่ฎก็ฎ็ๅญ็
ROUND(SUM(CASE WHEN days_since_first = 7 THEN active_users ELSE 0 END) * 100.0 /
NULLIF(SUM(CASE WHEN days_since_first = 0 THEN active_users ELSE 0 END), 0), 2) as day7_retention
FROM cohort_activity
GROUP BY cohort_date
ORDER BY cohort_date DESC;
็จๆท็ๅญๅๆ็พคๅๆ๏ผๆ้ฆๆฌกๅ
ๆขๅจๅ็ป๏ผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ็ฌฌ1ๅจ โ ็ฌฌ2ๅจ โ ็ฌฌ3ๅจ โ ็ฌฌ4ๅจ โ ็ฌฌ5ๅจ โ ็ฌฌ6ๅจ
โโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโ
2026-W01 โ 5,000 โ 3,250 โ 2,750 โ 2,400 โ 2,150 โ 1,950
โ 100% โ 65% โ 55% โ 48% โ 43% โ 39%
โโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโ
2026-W02 โ 6,200 โ 4,092 โ 3,224 โ 2,790 โ 2,480 โ
โ 100% โ 66% โ 52% โ 45% โ 40% โ
โโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโ
2026-W03 โ 4,800 โ 3,120 โ 2,544 โ 2,112 โ โ
โ 100% โ 65% โ 53% โ 44% โ โ
โโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโ
2026-W04 โ 7,500 โ 5,025 โ 3,975 โ โ โ
โ 100% โ 67% โ 53% โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ ๅๆ็ป่ฎบ๏ผ
โข ็ฌฌ2ๅจ็ๅญ็จณๅฎๅจ65-67%๏ผ่กจ็ฐ่ฏๅฅฝ
โข ็ฌฌ4ๅจ็ๅญ็บฆ44-48%๏ผๆๆๅ็ฉบ้ด
โข W04ๆนๆฌก็จๆท่ดจ้ๆไฝณ๏ผๅฏๆ็ปญๅ
ณๆณจ
5.5 ๅผๅธธๆฃๆตๆนๆณ
ๅฝๆฐๆฎ้ๅพๅคงๆถ๏ผ้ ไบบๅทฅๅ็ฐๅผๅธธๆฏไธ็ฐๅฎ็ใ้่ฆๅปบ็ซ่ชๅจๅ็ๅผๅธธๆฃๆตๆบๅถใ
ๅบไบๅๅฒๆฐๆฎ็ๅๅผๅๆ ๅๅทฎ่ฎพๅฎ้ๅผใ
-- ็ป่ฎก้ๅผๆณ๏ผ3ฯๅๅ
WITH daily_stats AS (
SELECT
redeem_date,
COUNT(*) as daily_redeems
FROM dwd_gift_code_redeem_detail
WHERE redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 90 DAY)
GROUP BY redeem_date
),
stats AS (
SELECT
AVG(daily_redeems) as mean_value,
STDDEV(daily_redeems) as std_value
FROM daily_stats
)
SELECT
d.redeem_date,
d.daily_redeems,
s.mean_value,
s.std_value,
(d.daily_redeems - s.mean_value) / s.std_value as z_score,
CASE
WHEN ABS((d.daily_redeems - s.mean_value) / s.std_value) > 3 THEN 'ANOMALY'
WHEN ABS((d.daily_redeems - s.mean_value) / s.std_value) > 2 THEN 'WARNING'
ELSE 'NORMAL'
END as status
FROM daily_stats d
CROSS JOIN stats s
ORDER BY ABS(z_score) DESC;
ไธไธไธไธชๅจๆๅฏนๆฏ๏ผๅๅ่ถ ่ฟ้ๅผๅๅ่ญฆใ
-- ็ฏๆฏๅๅๅ่ญฆ
SELECT
activity_id,
redeem_date,
daily_redeems,
prev_day_redeems,
ROUND((daily_redeems - prev_day_redeems) * 100.0 / NULLIF(prev_day_redeems, 0), 2) as change_pct,
CASE
WHEN change_pct > 50 THEN 'ALERT_UP' -- ไธๆถจ่ถ
่ฟ50%
WHEN change_pct < -50 THEN 'ALERT_DOWN' -- ไธ่ท่ถ
่ฟ50%
WHEN change_pct > 30 THEN 'WARNING_UP'
WHEN change_pct < -30 THEN 'WARNING_DOWN'
ELSE 'NORMAL'
END as status
FROM (
SELECT
activity_id,
redeem_date,
COUNT(*) as daily_redeems,
LAG(COUNT(*)) OVER (PARTITION BY activity_id ORDER BY redeem_date) as prev_day_redeems
FROM dwd_gift_code_redeem_detail
WHERE redeem_date >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
GROUP BY activity_id, redeem_date
) t
WHERE ABS(change_pct) > 30;
็ปๅๅๆฏๅ็ฏๆฏ๏ผๆดๅ็กฎๅฐๅคๆญๅผๅธธใ
-- ๅ็ฏๆฏ่ๅๆฃๆต
SELECT
metric_name,
metric_date,
current_value,
prev_day_value,
prev_week_value,
ROUND((current_value - prev_day_value) * 100.0 / NULLIF(prev_day_value, 0), 2) as dod_change,
ROUND((current_value - prev_week_value) * 100.0 / NULLIF(prev_week_value, 0), 2) as wow_change,
CASE
-- ๅ็ฏๆฏๅๆถๅคงๅน
ไธๆถจ/ไธ่ท๏ผๆดๅฏ่ฝๆฏ็ๅฎๅผๅธธ
WHEN dod_change > 30 AND wow_change > 30 THEN 'STRONG_ALERT_UP'
WHEN dod_change < -30 AND wow_change < -30 THEN 'STRONG_ALERT_DOWN'
-- ไป
็ฏๆฏๅๅ๏ผๅฏ่ฝๆฏๅจๆๆงๆณขๅจ
WHEN ABS(dod_change) > 30 AND ABS(wow_change) < 15 THEN 'WEAK_WARNING'
ELSE 'NORMAL'
END as alert_level
FROM daily_metrics
WHERE metric_date = CURRENT_DATE - INTERVAL 1 DAY;
ๅ ญใ่ฟ่ฅๅณ็ญๆฏๆ
ๆฐๆฎๅๆ็ๆ็ป็ฎ็๏ผๆฏๆฏๆ่ฟ่ฅๅณ็ญใๆฐๆฎไธๆฏ็ป็น๏ผๅณ็ญๆๆฏใ
6.1 ๆดปๅจไผๅๅณ็ญ
ๆ นๆฎๆฐๆฎ่ฐๆดๅฅๅฑ้ ็ฝฎ๏ผ
-- ๅฅๅฑๆๆๅๆ๏ผๆๅฏผไผๅ
SELECT
reward_type,
COUNT(*) as redeem_count,
AVG(day7_retention) as avg_retention,
AVG(pay_convert_rate) as avg_convert,
-- ็ปผๅ่ฏๅ = ็ญๅบฆ*0.3 + ็ๅญ*0.4 + ่ฝฌๅ*0.3
ROUND((redeem_count / max_redeems * 30) +
(avg_retention * 40) +
(avg_convert * 30), 2) as composite_score
FROM reward_analysis
GROUP BY reward_type
ORDER BY composite_score DESC;
๐ฏ ๅฅๅฑไผๅๅปบ่ฎฎ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ใไฟ็ใ้ป้็คผๅ
ใ้ป็ณ็คผๅ
โข ็ปผๅ่ฏๅ > 80
โข ็ๅญ่ดก็ฎ้ซ๏ผ็จๆทๆปกๆๅบฆ้ซ
ใไผๅใ็ฝ้ถ็คผๅ
โข ็ญๅบฆไธญ็ญ๏ผไฝ่ฝฌๅๅไฝ
โข ๅปบ่ฎฎ๏ผๅขๅ ้ขๅคๅฐๅฅๅฑๆๅๅธๅผๅ
ใๆฟๆขใ้ๅธ็คผๅ
โข ็ปผๅ่ฏๅ < 40
โข ็จๆทๅ้ฆ"ๅฅๅฑๅคชๅฐ"
โข ๅปบ่ฎฎ๏ผๆฟๆขไธบๆฝๅฅๅธๆ้ๆถ้ๅ
ท
6.2 ๆธ ้ไผๅๅณ็ญ
-- ๆธ ้ROI็ปผๅ่ฏไผฐ
SELECT
channel_name,
total_cost,
total_revenue,
ROUND(total_revenue / NULLIF(total_cost, 0), 2) as roi,
-- LTV้ขๆต๏ผ็ฎๅ็๏ผ30ๆฅๆถๅ
ฅ * 3๏ผ
ROUND(total_revenue_30d * 3 / NULLIF(total_cost, 0), 2) as predicted_ltv_roi,
-- ๅปบ่ฎฎๅจไฝ
CASE
WHEN roi >= 2 THEN 'SCALE_UP' -- ๆฉๅคงๆๆพ
WHEN roi >= 1 THEN 'MAINTAIN' -- ็ปดๆๆๆพ
WHEN roi >= 0.5 THEN 'OPTIMIZE' -- ไผๅๆๆพ
ELSE 'PAUSE' -- ๆๅๆๆพ
END as suggested_action
FROM channel_roi_summary
ORDER BY roi DESC;
6.3 ้ฃ้ฉ้ข่ญฆ็ณป็ป
-- ้ฃ้ฉ็ๆงไปช่กจ็SQL
SELECT
'้ซ้ขๅ
ๆข' as risk_type,
COUNT(*) as risk_count,
GROUP_CONCAT(DISTINCT code_id) as affected_codes
FROM (
SELECT code_id, COUNT(*) as cnt
FROM gift_code_redeem_log
WHERE redeem_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY code_id
HAVING cnt > 10
) t
UNION ALL
SELECT
'IPๅผๅธธ' as risk_type,
COUNT(DISTINCT redeem_ip) as risk_count,
GROUP_CONCAT(DISTINCT redeem_ip) as affected_ips
FROM gift_code_redeem_log
WHERE redeem_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY redeem_ip
HAVING COUNT(*) > 100
UNION ALL
SELECT
'่ฎพๅคๅ
ณ่' as risk_type,
COUNT(DISTINCT device_id) as risk_count,
''
FROM (
SELECT device_id, COUNT(DISTINCT user_id) as user_cnt
FROM gift_code_redeem_log
WHERE redeem_time >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY device_id
HAVING user_cnt > 5
) t;
``` โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ ้ฃ้ฉๆฃๆต โโโโโโถโ ้ฃ้ฉ่ฏไผฐ โโโโโโถโ ้ข่ญฆ้็ฅ โ โ (ๅฎๆถ็ๆง) โ โ (่ชๅจๅ็บง) โ โ (ๅคๆธ ้) โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ โผ โโโโโโโโโโโโโโโ โ ไบบๅทฅ็กฎ่ฎค โ โ (ๅฏ้) โ โโโโโโโโโโโโโโโ โ โผ โโโโโโโโโโโโโโโ โ ๅค็ฝฎๆชๆฝ โ โ (่ชๅจ/ๆๅจ) โ โ
๐ฌ ่ฏ่ฎบ (0)