Сравнение последней записи с предыдущей записью в postgresql - PullRequest
0 голосов
/ 02 февраля 2012

У меня есть таблица в БД PostgreSQL:

 Client | Rate | StartDate|EndDate     
 A      | 1000 | 2005-1-1 |2005-12-31
 A      | 2000 | 2006-1-1 |2006-12-31
 A      | 3000 | 2007-1-1 |2007-12-31  
 B      | 5000 | 2006-1-1 |2006-12-31  
 B      | 8000 | 2008-1-1 |2008-12-31  
 C      | 2000 | 2006-1-1 |2006-12-31  

Я хочу получить последнее изменение, например, эту таблицуКак?

 Client | Rate | StartDate|EndDate    |Pre Rate | Pre StartDate |Pre EndDate    
 A      | 3000 | 2007-1-1 |2007-12-31 | 2000    | 2006-1-1      |2006-12-31  
 B      | 8000 | 2008-1-1 |2008-12-31 | 5000    | 2006-1-1      |2006-12-31   
 C      | 2000 | 2006-1-1 |2006-12-31 

Ответы [ 3 ]

2 голосов
/ 14 февраля 2012
SELECT DISTINCT ON (Client) Client,
                            Rate,
                            StartDate,
                            EndDate,
                            LAG(Rate) OVER (PARTITION BY Client
                                            ORDER BY StartDate) AS "Pre Rate",
                            LAG(StartDate) OVER (PARTITION BY Client
                                                 ORDER BY StartDate) AS "Pre StartDate",
                            LAG(EndDate) OVER (PARTITION BY Client
                                               ORDER BY StartDate) AS "Pre EndDate"
FROM ClientRates
ORDER BY Client,
         StartDate DESC;
1 голос
/ 25 октября 2012

По сути такой же, как ответ Тима (+1), с некоторой полировкой и полным сценарием для попытки / проверки

CREATE TEMP TABLE client_rates (client VARCHAR, rate INTEGER, 
  start_date DATE, end_date DATE);
INSERT INTO client_rates VALUES ('A',1000,'2005-1-1','2005-12-31');
INSERT INTO client_rates VALUES ('A',2000,'2006-1-1','2006-12-31');
INSERT INTO client_rates VALUES ('A',3000,'2007-1-1','2007-12-31');
INSERT INTO client_rates VALUES ('B',5000,'2006-1-1','2006-12-31');
INSERT INTO client_rates VALUES ('B',8000,'2008-1-1','2008-12-31');
INSERT INTO client_rates VALUES ('C',2000,'2006-1-1','2006-12-31');

SELECT DISTINCT ON (client) * FROM 
(
SELECT client, rate, start_date, end_date, 
lag(rate)       OVER w1  AS prev_rate,
lag(start_date) OVER w1  AS prev_start_date,
lag(end_date)   OVER w1  AS prev_end_date
FROM client_rates
WINDOW w1 AS (PARTITION BY client ORDER BY start_date)
ORDER BY client,start_date desc
) AS foo;

 client | rate | start_date |  end_date  | prev_rate | prev_start_date | prev_end_date
--------+------+------------+------------+-----------+-----------------+---------------
 A      | 3000 | 2007-01-01 | 2007-12-31 |      2000 | 2006-01-01      | 2006-12-31
 B      | 8000 | 2008-01-01 | 2008-12-31 |      5000 | 2006-01-01      | 2006-12-31
 C      | 2000 | 2006-01-01 | 2006-12-31 |           |                 |
1 голос
/ 02 февраля 2012

Я не могу не думать, что есть более простой способ выразить это.

with current_start_dates as (
  select client, max(startdate) cur_startdate
  from client_rates
  group by client
),
extended_client_rates as (
  select client, rate, startdate, enddate, 
    lag(rate, 1) over (partition by client order by startdate) prev_rate,
    lag(startdate,1) over (partition by client order by startdate) prev_startdate,
    lag(enddate,1) over (partition by client order by startdate) prev_enddate
  from client_rates
)
select cr.* 
from extended_client_rates cr
inner join current_start_dates csd on csd.client = cr.client 
                                  and csd.cur_startdate = cr.startdate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...