Sql 红移:查找上一模式的最大级别

Sql 红移:查找上一模式的最大级别,sql,amazon-redshift,Sql,Amazon Redshift,我有一个用户表,用于存储每个类别完成的级别。 用户可以在第一个类别完成几级后解锁第二个和第三个类别 我的目标是找到他们解锁其他类别的级别(在第一个类别中) 注意:数据不是原始数据 例如: | times | users | levels | mode | |----------------------------|-------|-----------|---------| | 2019-07-30 10:39:55.000000 | A

我有一个用户表,用于存储每个类别完成的级别。 用户可以在第一个类别完成几级后解锁第二个和第三个类别

我的目标是找到他们解锁其他类别的级别(在第一个类别中)

注意:数据不是原始数据

例如:

|               times        | users | levels    |    mode | 
|----------------------------|-------|-----------|---------|
| 2019-07-30 10:39:55.000000 | A     |  1        |  First  |  
| 2019-07-30 10:43:16.000000 | A     |  2        |  First  |  
| 2019-07-30 10:45:03.000000 | A     |  3        |  First  |  
| 2019-07-30 10:47:20.000000 | A     |  999      |  Second |  
| 2019-07-30 10:49:50.000000 | A     |  999      |  Second | 
| 2019-07-30 20:21:39.000000 | B     |  1        |  First  |  
| 2019-07-31 11:10:35.000000 | B     |  2        |  First  |  
| 2019-07-31 11:11:51.000000 | B     |  3        |  First  |  
| 2019-07-31 11:13:01.000000 | B     |  4        |  First  |  
| 2019-07-31 11:15:11.000000 | B     |  5        |  First  | 
| 2019-07-31 11:17:24.000000 | B     |  999      |  Third  | 
| 2019-08-01 02:16:13.000000 | B     |  999      |  Second | 
| 2019-08-01 02:29:31.000000 | A     |  4        |  First  | 
| 2019-08-01 08:04:01.000000 | A     |  5        |  First  | 
| 2019-08-01 08:06:27.000000 | A     |  999      |  Third  |
| 2019-08-01 08:10:02.000000 | A     |  1        |  First  |
| 2019-08-01 08:12:29.000000 | A     |  999      |  Second |
| 2019-08-02 04:45:43.000000 | A     |  999      |  Third  |
| 2019-08-02 07:42:35.000000 | C     |  1        |  First  |
| 2019-08-02 08:12:30.000000 | C     |  2        |  First  |
| 2019-08-02 08:15:53.000000 | C     |  3        |  First  |
| 2019-08-02 08:17:24.000000 | D     |  1        |  First  |
所以

注意:只有第一个类别具有级别,其他类别为固定级别(999)

我尝试在分区上使用
Lag()
,并获取第一个类别级别的最新值:

SELECT users,
       times,
       levels,
       mode,
       rnk,
       lag(levels, 1) OVER (PARTITION BY users ORDER BY times, mode) last_story_level
FROM (
       SELECT users
              times,
              CASE WHEN mode = 'First' THEN levels ELSE NULL END levels,
              mode,
         -- rnk will I use rnk=1 for the first value of each mode
         row_number() OVER (PARTITION BY mode, users ORDER BY times) rnk
       FROM my_table
       ORDER BY times
     )
结果是:

|               time        | user | level    |    mode | rnk| last_story_level|
|----------------------------|-----------------|---   |-------|---|---|
| 2019-07-30 10:39:55.000000 | A    |  1    |  First   | 1 | NULL |
| 2019-07-30 10:43:16.000000 | A    |  2    |  First   | 2 | 1   |
| 2019-07-30 10:45:03.000000 | A    |  3    |  First   | 3 | 2   |
| 2019-07-30 10:47:20.000000 | A    |  NULL  |  Second | 1  |3  |
| 2019-07-30 10:49:50.000000 | A    |  NULL  |  Second | 2 |NULL|
| 2019-07-30 20:21:39.000000 | B    |  1    |  First   | 1 |NULL|
| 2019-07-31 11:10:35.000000 | B    |  2    |  First   | 2 |1  |
| 2019-07-31 11:11:51.000000 | B    |  3    |  First   | 3 |2  |
| 2019-07-31 11:13:01.000000 | B    |  4    |  First   | 4 |3  |
| 2019-07-31 11:15:11.000000 | B    |  5    |  First   | 5 |4  |
| 2019-07-31 11:17:24.000000 | B    |  NULL |  Third   | 1 |5  |
| 2019-08-01 02:16:13.000000 | B    |  NULL |  Second  | 1 |NULL|
| 2019-08-01 02:29:31.000000 | A    |  4    |  First   | 4 |NULL|
| 2019-08-01 08:04:01.000000 | A    |  5    |  First   | 5 |4  |
| 2019-08-01 08:06:27.000000 | A    |  NULL |  Third   | 1 |5  |
| 2019-08-01 08:10:02.000000 | A    |  1    |  First   | 6 |NULL|
| 2019-08-01 08:12:29.000000 | A    |  NULL | Second   | 3 |1  |
| 2019-08-02 04:45:43.000000 | A    |  NULL | Third    | 2 |NULL|
| 2019-08-02 07:42:35.000000 | C    |  1    | First    | 1 |NULL|
| 2019-08-02 08:12:30.000000 | C    |  2    | First    | 2 |1  |
| 2019-08-02 08:15:53.000000 | C    |  3    | First    | 3 |2  |
| 2019-08-02 08:17:24.000000 | D    |  1    | First    | 1 |NULL|
问题是当用户再次重复较低级别时,最后一个值不再是最高级别

所以我想说的是:

|               time         | user    | last_story_level|    mode |  
|----------------------------|-------|----------|--------   |
| 2019-07-30 10:47:20.000000 | A    |  3       |  Second     | 
| 2019-08-01 08:06:27.000000 | A    |  5       |  Third     | 
| 2019-07-31 11:17:24.000000 | B    |  5       |  Third     | 
| 2019-08-01 02:16:13.000000 | B    |  5       |  Second    |
| 2019-08-02 08:15:53.000000 | C    |  3       |  Not open any category    | 
| 2019-08-02 08:17:24.000000 | D    |  1       | Not open any category    |  

如果我理解正确,您希望在每个用户第一次进入“下一个”模式时,为“第一个”设置前一个最高值
level

您可以使用累积最大值来获取“First”的上一级别,然后使用
distinct on
来获取每个用户/模式仅一行:

select distinct on (user, mode) t.*
from (select t.*,
             max(case when mode = 'First' then level end) over 
                 (partition by user
                  order by time
                  rows between unbounded preceding and current row
                 ) as prev_first_level
      from my_table t
     ) t
order by user, mode, time;
编辑:

在红移中,您可以执行以下操作:

select t.*
from (select t.*,
             max(case when mode = 'First' then level end) over 
                 (partition by user
                  order by time
                  rows between unbounded preceding and current row
                 ) as prev_first_level,
           row_number() over (partition by user, mode order by time) as seqnum
      from my_table t
     ) t
where seqnum = 1;

Distinct on
Redshift
上不起作用,但是您的
max()over(partition by)
解决方案对我帮助很大。“这应该是可以接受的答案,谢谢你,”戈登说Linoff@Axis . . . 我添加了一个红移安全版本。
select t.*
from (select t.*,
             max(case when mode = 'First' then level end) over 
                 (partition by user
                  order by time
                  rows between unbounded preceding and current row
                 ) as prev_first_level,
           row_number() over (partition by user, mode order by time) as seqnum
      from my_table t
     ) t
where seqnum = 1;