获得每个客户最近的两个日期

时间:2017-06-08 13:23:14

标签: sql postgresql

基本上,我需要检索至少在两个不同日期购买的客户的最后两个日期,这意味着有一些客户仅在一个日期购买,数据具有以下形式

client_id  date
1          2016-07-02
1          2016-07-02
1          2016-06-01
2          2015-06-01

我希望以下列形式获取

client_id      previous_date     last_date
1              2016-06-01        2016-07-02

remarques:

客户可以在同一日期拥有多个条目

客户只能有一个日期的条目,这样的客户应该被丢弃

4 个答案:

答案 0 :(得分:2)

使用@Builder.Default为您的日期排名。然后按client_id分组并显示最后的日期(排名#1和#2)。

DENSE_RANK

答案 1 :(得分:1)

UNTESTED:

我们使用公用表表达式根据日期降序分配行号,然后仅包含行号<= 2的那些记录,然后确保具有1行的那些记录被排除。< / p>

WITH CTE AS (
  SELECT Distinct Client_ID
       , Date
       , row_number() over (partition by clientID order by date desc) rn 
  FROM Table)

SELECT  Client_ID, min(date) previous_date, max(date) last_date)
FROM CTE
WHERE RN <=2 
GROUP BY Client_ID
HAVING max(RN) > 1

答案 2 :(得分:1)

你只需要一个小组......

--test date
declare  @tablename TABLE
(
    client_id int,
    [date] datetime
);

insert into @tablename
values( 1 , '2016-07-02'),
   (1 , '2016-07-02'),
   (1 , '2016-06-01'),
   (2 , '2015-06-01');

--query
SELECT client_id,MIN([DATE]) AS [PREVIOUS_DATE], MAX([DATE]) AS [LAST_DATE]
FROM @tablename
GROUP BY client_id

更新

-- create data
create table myTable
(
    client_id integer,
    given_date date
);

insert into myTable
values( 1 ,  '2016-07-02'),
   (1 ,  '2016-07-02'),
   (1 , '2016-06-01'),
   (1 , '2016-06-03'),
   (1 , '2016-06-09'),
   (2 , '2015-06-01'),
   (3 , '2016-06-03'),
   (3 , '2016-06-09');

-- query
SELECT sub.client_id, sub.PREVIOUS_DATE, sub.LAST_DATE
FROM
 (select 
   ROW_NUMBER() OVER (PARTITION BY a.client_id order by b.given_date desc,(MAX(b.given_date) - a.given_date)) AS ROW_NUMBER,
   a.client_id,a.given_date AS PREVIOUS_DATE, MAX(b.given_date) - a.given_date AS diff, (b.given_date) AS LAST_DATE
    FROM myTable AS a 
      JOIN myTable AS b
        ON b.client_id = a.client_id 
    WHERE a.given_date <> b.given_date
    group by a.client_id, a.given_date, b.given_date) AS sub
WHERE sub.ROW_NUMBER = 1

答案 3 :(得分:1)

建立:

t=# create table s153 (c int,  d date);
CREATE TABLE
t=# insert into s153 values (1,'2016-07-02'), (1,'2016-07-02'),(1,'2016-06-01'),(2,'2016-06-01');
INSERT 0 4

查询:

t=# with a as (
select distinct c,d from s153
)
, b as (
select c,nth_value(d,1) over (partition by c order by d) last_date, nth_value(d,2) over (partition by c order by d) prev_date
from a
)
select * from b where prev_date is not null
;
 c | last_date  | prev_date
---+------------+------------
 1 | 2016-06-01 | 2016-07-02
(1 row)