Ситуация:
У меня есть таблица с тремя столбцами:
- свидание
- игра
- ID пользователя
Из этой таблицы мне нужно создать таблицу хранения, которая в конечном итоге будет выглядеть так:
Вывод:
+------------+-------------+------+-------------+------+------+-------+
| date | game | day0 | day1 | day3 | day7 | day10 |
+------------+-------------+------+-------------+------+------+-------+
| 2019-01-01 | fifa | 100 | % of day 0 | | | |
| 2019-01-01 | nba | 100 | | | | |
| 2019-01-01 | battlefield | 100 | | | | |
| 2019-01-02 | fifa | 100 | | | | |
| 2019-01-02 | battlefield | 100 | | | | |
| 2019-01-03 | fifa | 100 | | | | |
| 2019-01-03 | nba | 100 | | | | |
| ... | | | | | | |
+------------+-------------+------+-------------+------+------+-------+
day0 равно 100, если хотя бы один человек играл в игру
day1 — это доля отдельных пользователей, которые вернулись через 1 или 2 дня.
day3 — это доля отдельных пользователей, которые вернулись через 3–6 дней.
и так далее...
если вы нанесете числа, это должно дать вам нелинейную убывающую кривую.
Логика:
(см. примеры данных ниже)
Скелет, который я построил до сих пор, выглядит так:
;WITH
baseDate AS (
SELECT
'target_date' AS [key_name]
,CAST('2019-01-01' AS date) AS [key_value]
),
durationDate AS (
SELECT DATEADD(DAY,0,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
UNION ALL
SELECT DATEADD(DAY,1,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
UNION ALL
SELECT DATEADD(DAY,2,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
UNION ALL
SELECT DATEADD(DAY,3,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
UNION ALL
SELECT DATEADD(DAY,4,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
UNION ALL
SELECT DATEADD(DAY,5,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
UNION ALL
SELECT DATEADD(DAY,6,key_value) AS target_date FROM baseDate WHERE [key_name] = 'target_date'
)
select
dd.target_date
, play.game
, play.[count]/play.count *100 as day0
from durationDate as dd
left join (
select t1.date, t1.game, COUNT(distinct t1.user_id) as [count]
from #t1 t1
group by t1.date, t1.game
) as play on dd.target_date=play.[date]
Вероятно, мне не хватает другой базовой таблицы для столбцов day1, day3, day7, например:
durationDateColumn AS (
SELECT
DATEADD(DAY,0,key_value) AS day1
, DATEADD(DAY,1,key_value) AS day2
, DATEADD(DAY,2,key_value) AS day3
, DATEADD(DAY,3,key_value) AS day4
, DATEADD(DAY,4,key_value) AS day5
, DATEADD(DAY,5,key_value) AS day6
, DATEADD(DAY,6,key_value) AS day7
FROM baseDate
WHERE [key_name] = 'target_date'
)
если нет более эффективного способа сделать это.
Пример данных:
drop table if exists #t1
create table #t1 ([date] date, [game] varchar (20),[user_id] bigint)
insert into #t1 values
('2019-01-01', 'fifa',11),
('2019-01-01', 'fifa',12),
('2019-01-01', 'fifa',13),
('2019-01-01', 'fifa',14),
('2019-01-02', 'fifa',12),
('2019-01-02', 'fifa',13),
('2019-01-02', 'fifa',14),
('2019-01-04', 'fifa',12),
('2019-01-04', 'fifa',13),
('2019-01-08', 'fifa',13),
('2019-01-01', 'nba',11),
('2019-01-01', 'nba',13),
('2019-01-01', 'nba',14),
('2019-01-02', 'nba',13),
('2019-01-02', 'nba',14),
('2019-01-04', 'nba',13),
('2019-01-08', 'nba',13)