Get the last two dates for each client

basically, I need to get the last two dates for customers who purchased at least two different dates, implying that there are some customers who only bought on one date, the data is of the following form

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

      

and I would like to receive it in the following form

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

      

Notes:

a customer can have multiple entries for the same date

a client can only have entries for one date, such a client should be discarded

+3


source to share


4 answers


Rank your dates with DENSE_RANK

. Then group by client_id and show the latest dates (ranked # 1 and # 2).



select
  client_id,
  max(case when rn = 2 then date end) as previous_date,
  max(case when rn = 1 then date end) as last_date
from
(
  select 
    client_id, 
    date, 
    dense_rank() over (partition by client_id order by date desc) as rn
  from mytable
)
group by client_id
having max(rn) > 1;

      

+2


source


UNTESTED:

We use a generic table expression to assign a row number based on a date in descending order and then only include those records that have a row number <= 2 and then make sure those with 1 row are excluded by the presence.



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

      

+1


source


<s> All you need is a group ...

--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

      

Updated

-- 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

      

+1


source


create:

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

      

request:

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)

      

+1


source







All Articles