排名仅在行值变化时增加

时间:2017-09-08 14:09:32

标签: sql postgresql rank dense-rank

我使用psql排名和分区功能来创建一个表格,描述旅行中拍摄的照片序列,其中id是图片ID,nsid是摄影师ID,位置是照片的拍摄地点,和排名是旅行期间拍摄照片的顺序(由相同date_trunc时间段内的照片定义)。

id  |nsid           |location   |date_taken |time_taken |date_trunc |rank   
1   |10000137@N04   |11         |08/03/2006 |18:42:02   |2006-03-06 |1      
2   |10000137@N04   |11         |08/03/2006 |18:56:44   |2006-03-06 |2      
3   |10000137@N04   |446        |12/09/2007 |01:05:27   |2007-09-10 |1      
4   |10000137@N04   |4          |12/09/2007 |01:05:35   |2007-09-10 |2      
5   |10000137@N04   |4          |12/09/2007 |01:05:41   |2007-09-10 |3      
6   |10000137@N04   |56         |12/09/2007 |01:05:45   |2007-09-10 |4      
7   |10000137@N04   |11         |03/07/2008 |09:21:54   |2008-06-30 |1      
8   |10000137@N04   |3199       |09/03/2013 |16:37:40   |2013-03-04 |1      
9   |10000137@N04   |4          |09/03/2013 |18:56:55   |2013-03-04 |2      
10  |10000280@N07   |215        |02/08/2007 |17:25:43   |2007-07-30 |1      
11  |10000280@N07   |215        |03/08/2007 |19:35:11   |2007-07-30 |2      
12  |100006043@N02  |203        |05/08/2013 |14:02:49   |2013-07-29 |1      
13  |100006043@N02  |1          |05/08/2013 |18:08:45   |2013-07-29 |2      
14  |100010324@N02  |1          |14/04/2013 |19:19:13   |2013-04-08 |1      
15  |100010343@N03  |367        |04/06/2014 |18:54:13   |2014-06-02 |1      
16  |100014982@N03  |2909       |28/08/2013 |23:20:27   |2013-08-26 |1      
17  |100014982@N03  |183        |13/09/2013 |12:26:41   |2013-09-09 |1      
18  |100018928@N06  |1149       |01/08/2013 |08:40:22   |2013-07-29 |1      
19  |100018928@N06  |1149       |01/08/2013 |08:40:23   |2013-07-29 |2      
20  |100018928@N06  |1149       |01/08/2013 |08:40:32   |2013-07-29 |3      
21  |100018928@N06  |1149       |01/08/2013 |08:40:33   |2013-07-29 |4      
22  |100021169@N02  |10         |02/07/2005 |18:17:26   |2005-06-27 |1      
23  |100021169@N02  |10         |02/07/2005 |18:18:13   |2005-06-27 |2

我想创建一个名为location_rank的新列,它是访问该位置的顺序位置。因此,同一旅行中由相同用户用户在相同位置拍摄的照片将具有相同的location_rank,并且location_rank值仅对于在该用户的旅行期间访问的每个新位置而增加(即,仅当位置值改变时从分区中的上一行开始)。所以所需的表格如下所示:

id |nsid          |location |date_taken|time_taken|date_trunc  |rank|location_rank
1  |10000137@N04  |11       |08/03/06  |18:42:02  |2006-01-01  |1   |1
2  |10000137@N04  |11       |08/03/06  |18:56:44  |2006-01-01  |2   |1
3  |10000137@N04  |446      |12/09/07  |01:05:27  |2007-01-01  |1   |1
4  |10000137@N04  |4        |12/09/07  |01:05:35  |2007-01-01  |2   |2
5  |10000137@N04  |4        |12/09/07  |01:05:41  |2007-01-01  |3   |2
6  |10000137@N04  |56       |12/09/07  |01:05:45  |2007-01-01  |4   |3
7  |10000137@N04  |11       |03/07/08  |09:21:54  |2008-01-01  |1   |1
8  |10000137@N04  |3199     |09/03/13  |16:37:40  |2013-01-01  |1   |1
9  |10000137@N04  |4        |09/03/13  |18:56:55  |2013-01-01  |2   |2
10 |10000280@N07  |215      |02/08/07  |17:25:43  |2007-01-01  |1   |1
11 |10000280@N07  |215      |03/08/07  |19:35:11  |2007-01-01  |2   |1
12 |100006043@N02 |203      |05/08/13  |14:02:49  |2013-01-01  |1   |1
13 |100006043@N02 |1        |05/08/13  |18:08:45  |2013-01-01  |2   |2
14 |100010324@N02 |1        |14/04/13  |19:19:13  |2013-01-01  |1   |1
15 |100010343@N03 |367      |04/06/14  |18:54:13  |2014-01-01  |1   |1
16 |100014982@N03 |2909     |28/08/13  |23:20:27  |2013-01-01  |1   |1
17 |100014982@N03 |183      |13/09/13  |12:26:41  |2013-01-01  |2   |2
18 |100018928@N06 |1149     |01/08/13  |08:40:22  |2013-01-01  |1   |1
19 |100018928@N06 |1149     |01/08/13  |08:40:23  |2013-01-01  |2   |1
20 |100018928@N06 |1149     |01/08/13  |08:40:32  |2013-01-01  |3   |1
21 |100018928@N06 |1149     |01/08/13  |08:40:33  |2013-01-01  |4   |1
22 |100021169@N02 |10       |02/07/05  |18:17:26  |2005-01-01  |1   |1
23 |100021169@N02 |10       |02/07/05  |18:18:13  |2005-01-01  |2   |1
24 |10002296@N02  |25       |12/03/11  |13:41:10  |2011-01-01  |1   |1
25 |10002296@N02  |25       |12/03/11  |13:42:19  |2011-01-01  |2   |1
26 |10002296@N02  |25       |12/03/11  |14:00:49  |2011-01-01  |3   |1
27 |10002296@N02  |25       |12/03/11  |14:07:57  |2011-01-01  |4   |1
28 |10002296@N02  |25       |12/03/11  |14:10:12  |2011-01-01  |5   |1
29 |10002450@N05  |105      |07/08/11  |02:43:45  |2011-01-01  |1   |1
30 |10002450@N05  |5        |07/08/11  |05:19:27  |2011-01-01  |2   |2
31 |100025689@N07 |966      |28/10/13  |20:19:05  |2013-01-01  |1   |1
32 |100025689@N07 |966      |28/10/13  |20:35:38  |2013-01-01  |2   |1
33 |100025689@N07 |966      |28/10/13  |20:35:55  |2013-01-01  |3   |1
34 |100025689@N07 |966      |28/10/13  |21:09:53  |2013-01-01  |4   |1
35 |100025689@N07 |966      |28/10/13  |21:27:50  |2013-01-01  |5   |1
36 |100029993@N07 |831      |27/09/14  |18:27:24  |2014-01-01  |1   |1
37 |100029993@N07 |3708     |09/10/14  |20:36:42  |2014-01-01  |2   |2
38 |100033343@N05 |42       |31/10/14  |12:23:50  |2014-01-01  |1   |1
39 |10003453@N03  |16       |28/08/09  |13:46:44  |2009-01-01  |1   |1
40 |10003453@N03  |186      |28/08/09  |14:17:39  |2009-01-01  |2   |2
41 |10003453@N03  |19       |28/08/09  |16:43:07  |2009-01-01  |3   |3
42 |10003453@N03  |2919     |29/08/09  |12:18:10  |2009-01-01  |4   |4
43 |10003453@N03  |2453     |29/08/09  |13:22:12  |2009-01-01  |5   |5
44 |10003453@N03  |262      |29/08/09  |15:59:14  |2009-01-01  |6   |6
45 |10003453@N03  |22       |30/08/09  |15:26:56  |2009-01-01  |7   |7
46 |10003453@N03  |33       |30/08/09  |16:25:30  |2009-01-01  |8   |8
47 |10003453@N03  |2914     |30/08/09  |21:29:39  |2009-01-01  |9   |9
48 |10003453@N03  |408      |03/09/09  |23:36:12  |2009-01-01  |10  |10
49 |10003453@N03  |133      |06/09/09  |21:57:03  |2009-01-01  |11  |11
50 |10003453@N03  |713      |16/09/09  |00:01:53  |2009-01-01  |12  |12

我尝试过使用dense_rank函数但是我没有成功。我非常感谢您在创建location_rank专栏时提供的帮助。

以下是我不成功尝试的dense_rank查询:

create table prep.location_rank2 as 
select 
    id, nsid, 
    location,date_taken,time_taken,date_trunc, rank, 
    dense_rank() over(
        partition by nsid, date_trunc 
        order by date_taken, time_taken, location, rank
    ) as location_rank 
from prep.test 
order by nsid; 

1 个答案:

答案 0 :(得分:0)

SELECT id,
       nsid,
       location,
       date_taken,
       time_taken,
       date_trunc,
       [rank],
       DENSE_RANK() OVER (PARTITION BY nsid, date_trunc 
                              ORDER BY CASE WHEN [rank] = rnum
                                            THEN location
                                            ELSE CAST(CONCAT(CAST([rank]-rnum AS VARCHAR), CAST(location AS VARCHAR)) AS INT)
                                        END) location_rank
  FROM (SELECT *, 
               ROW_NUMBER() OVER (PARTITION BY nsid, date_trunc 
                                      ORDER BY location) rnum
          FROM photo_trip
       ) a
 ORDER BY id;

结果

id  nsid            location    date_taken  time_taken          date_trunc  rank    location_rank
1   10000137@N04    11          2006-03-08  18:42:02.0000000    2006-03-06  1       1
2   10000137@N04    11          2006-03-08  18:56:44.0000000    2006-03-06  2       1
3   10000137@N04    446         2007-09-12  01:05:27.0000000    2007-09-10  1       1
4   10000137@N04    4           2007-09-12  01:05:35.0000000    2007-09-10  2       2
5   10000137@N04    4           2007-09-12  01:05:41.0000000    2007-09-10  3       2
6   10000137@N04    56          2007-09-12  01:05:45.0000000    2007-09-10  4       3
7   10000137@N04    11          2008-07-03  09:21:54.0000000    2008-06-30  1       1
8   10000137@N04    3199        2013-03-09  16:37:40.0000000    2013-03-04  1       1
9   10000137@N04    4           2013-03-09  18:56:55.0000000    2013-03-04  2       2
10  10000280@N07    215         2007-08-02  17:25:43.0000000    2007-07-30  1       1
11  10000280@N07    215         2007-08-03  19:35:11.0000000    2007-07-30  2       1
12  100006043@N02   203         2013-08-05  14:02:49.0000000    2013-07-29  1       1
13  100006043@N02   1           2013-08-05  18:08:45.0000000    2013-07-29  2       2
14  100010324@N02   1           2013-04-14  19:19:13.0000000    2013-04-08  1       1
15  100010343@N03   367         2014-06-04  18:54:13.0000000    2014-06-02  1       1
16  100014982@N03   2909        2013-08-28  23:20:27.0000000    2013-08-26  1       1
17  100014982@N03   183         2013-09-13  12:26:41.0000000    2013-09-09  1       1
18  100018928@N06   1149        2013-08-01  08:40:22.0000000    2013-07-29  1       1
19  100018928@N06   1149        2013-08-01  08:40:23.0000000    2013-07-29  2       1
20  100018928@N06   1149        2013-08-01  08:40:32.0000000    2013-07-29  3       1
21  100018928@N06   1149        2013-08-01  08:40:33.0000000    2013-07-29  4       1
22  100021169@N02   10          2005-07-02  18:17:26.0000000    2005-06-27  1       1
23  100021169@N02   10          2005-07-02  18:18:13.0000000    2005-06-27  2       1