2017-07-28 36 views
0

我有一个表,看起来像:PostgreSQL的 - 等级超过在0块上市行1

id  code  date1   date2   block 
-------------------------------------------------- 
20  1234  2017-07-01 2017-07-31 1 
15  1234  2017-06-01 2017-06-30 1 
13  1234  2017-05-01 2017-05-31 0 
11  1234  2017-03-01 2017-03-31 0 
9  1234  2017-02-01 2017-02-28 1 
8  1234  2017-01-01 2017-01-31 0 
7  1234  2016-11-01 2016-11-31 0 
6  1234  2016-10-01 2016-10-31 1 
2  1234  2016-09-01 2016-09-31 1 

我需要根据0和1的,像块进行排名的行:

id  code  date1   date2   block  desired_rank 
------------------------------------------------------------------- 
20  1234  2017-07-01 2017-07-31 1   1 
15  1234  2017-06-01 2017-06-30 1   1 
13  1234  2017-05-01 2017-05-31 0   2 
11  1234  2017-03-01 2017-03-31 0   2 
9  1234  2017-02-01 2017-02-28 1   3 
8  1234  2017-01-01 2017-01-31 0   4 
7  1234  2016-11-01 2016-11-31 0   4 
6  1234  2016-10-01 2016-10-31 1   5 
2  1234  2016-09-01 2016-09-31 1   5 

我试着使用秩()和DENSE_RANK(),但结果我最终是:

id  code  date1   date2   block  dense_rank() 
------------------------------------------------------------------- 
20  1234  2017-07-01 2017-07-31 1   1 
15  1234  2017-06-01 2017-06-30 1   2 
13  1234  2017-05-01 2017-05-31 0   1 
11  1234  2017-03-01 2017-03-31 0   2 
9  1234  2017-02-01 2017-02-28 1   3 
8  1234  2017-01-01 2017-01-31 0   3 
7  1234  2016-11-01 2016-11-31 0   4 
6  1234  2016-10-01 2016-10-31 1   4 
2  1234  2016-09-01 2016-09-31 1   5 

在最后一个表中,排名并不关心行,它只是将所有1和0作为一个单位,并设置从第一个1和第0个开始的递增计数。 我的查询是这样的:

CREATE TEMP TABLE data (id integer,code text, date1 date, date2 date, block integer); 

INSERT INTO data VALUES 
(20,'1234', '2017-07-01','2017-07-31',1), 
(15,'1234', '2017-06-01','2017-06-30',1), 
(13,'1234', '2017-05-01','2017-05-31',0), 
(11,'1234', '2017-03-01','2017-03-31',0), 
(9, '1234', '2017-02-01','2017-02-28',1), 
(8, '1234', '2017-01-01','2017-01-31',0), 
(7, '1234', '2016-11-01','2016-11-30',0), 
(6, '1234', '2016-10-01','2016-10-31',1), 
(2, '1234', '2016-09-01','2016-09-30',1); 

SELECT *,dense_rank() OVER (PARTITION BY code,block ORDER BY date2 DESC) 
FROM data 
ORDER BY date2 DESC; 

顺便说一下,数据库是在postgreSQL。

我希望有一个变通方法...谢谢:)

编辑:注意0和1的块是不相等的。

+0

试试这个,从分区中删除块和date2的,块使用顺序。 –

回答

1

有没有办法得到这个结果使用窗口功能:

SELECT *, 
    Sum(flag) -- now sum the 0/1 to create the "rank" 
    Over (PARTITION BY code 
     ORDER BY date2 DESC) 
FROM 
(
    SELECT *, 
     CASE 
     WHEN Lag(block) -- check if this is the 1st row of a new block 
       Over (PARTITION BY code 
        ORDER BY date2 DESC) = block 
     THEN 0 
     ELSE 1 
     END AS flag 
    FROM DATA 
) AS dt 
+0

哇...它的工作!谢谢,我是新的窗口功能,但它似乎是最好的解决方案。谢谢。 – Dan