Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 根据玩过的游戏创建保留表_Sql_Sql Server_Retention - Fatal编程技术网

Sql 根据玩过的游戏创建保留表

Sql 根据玩过的游戏创建保留表,sql,sql-server,retention,Sql,Sql Server,Retention,情况: +------------+-------------+------+-------------+------+------+-------+ | date | game | day0 | day1 | day3 | day7 | day10 | +------------+-------------+------+-------------+------+------+-------+ | 2019-01-01 | fifa |

情况:

+------------+-------------+------+-------------+------+------+-------+
|    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 |             |      |      |       |
| ...        |             |      |             |      |      |       |
+------------+-------------+------+-------------+------+------+-------+
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)
我有一个有三列的表:

  • 日期
  • 游戏
  • 用户id
从该表中,我需要创建一个保留表,它最终将如下所示:

;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]
输出:

+------------+-------------+------+-------------+------+------+-------+
|    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 |             |      |      |       |
| ...        |             |      |             |      |      |       |
+------------+-------------+------+-------------+------+------+-------+
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)
如果至少有一人玩游戏,则第0天为100

day1是1或2天后返回的不同用户的比例

day3是在3到6天后返回的不同用户的比例

等等

如果你画出这些数字,它会给你一条非线性递减曲线

逻辑:

+------------+-------------+------+-------------+------+------+-------+
|    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 |             |      |      |       |
| ...        |             |      |             |      |      |       |
+------------+-------------+------+-------------+------+------+-------+
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)
(见下面的示例数据)

到目前为止,我构建的骨架如下所示:

;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]
我可能缺少第1、第3、第7列的另一个基表,例如:

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'
    )
除非有更有效的方法

样本数据:

+------------+-------------+------+-------------+------+------+-------+
|    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 |             |      |      |       |
| ...        |             |      |             |      |      |       |
+------------+-------------+------+-------------+------+------+-------+
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)

加入日期和后续日期数据,计算天数和用户数。按使用条件聚合的天数透视

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);

select [date], [game] 
  , 100.0 day0
  , cast(100.0 * (0.0 + sum(case ret when 1 then n else 0 end)) / sum(case ret when 0 then n end) as decimal(5,2)) day1
  , cast(100.0 * (0.0 + sum(case ret when 2 then n else 0 end)) / sum(case ret when 0 then n end) as decimal(5,2)) day2
  , cast(100.0 * (0.0 + sum(case ret when 3 then n else 0 end)) / sum(case ret when 0 then n end) as decimal(5,2)) day3
  , cast(100.0 * (0.0 + sum(case ret when 4 then n else 0 end)) / sum(case ret when 0 then n end) as decimal(5,2)) day4
  -- .. more days
from (
    select t1.[date], t1.[game], Datediff(dd, t1.[Date], t2.[Date]) ret, count(distinct t1.[user_id]) n
    from #t1 t1
    left join #t1 t2
        on t1.game = t2.game and t1.user_id = t2.user_id and t1.date <= t2.date
    group by t1.[date], t1.[game], Datediff(dd, t1.[Date], t2.[Date])
) evt
group by [date], [game]
order by [date], [game];

如果第6天返回的用户比第2天多,则不确定曲线是如何减少的。通常情况下,这是保留期的情况,我的示例数据不具有代表性,我将对其进行更改。非常感谢。