简体   繁体   English

如何编写 LAG() Function 以计算 PROC SQL SAS 中的日期差异

[英]How to Write LAG() Function to Calculate Date Difference in PROC SQL SAS

I am trying to write a code in SQL SAS to calculate difference of days when a user was seen.我正在尝试在 SQL SAS 中编写代码来计算看到用户的天数差异。

As an example of a raw data is following:作为原始数据的示例如下:

USER     DATE
User1    20200516
User1    20200513
User1    20200501
User2    20200515
User2    20200511

How to write a LAG() Function so the output table should look like following:如何编写 LAG() Function 所以 output 表应如下所示:

USER     DATE       PREV_DATE    DIFF
User1    20200516   20200513     3
User1    20200513   20200501     12
User2    20200515   20200511     4

I don't use sas so please take my answer as hint for usage of lag function, other issues such as date conversion or computing difference is up to you.我不使用 sas 所以请以我的回答作为使用lag function 的提示,日期转换或计算差异等其他问题取决于您。 This is solution in Postgres (columns renamed to avoid clashes):这是 Postgres 中的解决方案(列重命名以避免冲突):

with t(user_col,date_col) as (values
  ('User1', date '2020-05-16'),
  ('User1', date '2020-05-13'),
  ('User1', date '2020-05-01'),
  ('User2', date '2020-05-15'),
  ('User2', date '2020-05-11')
), lags as (
  select user_col
       , date_col
       , lag(date_col) over (partition by user_col order by date_col) as prev_date
  from t
)
select user_col, date_col, prev_date, date_col - prev_date as diff
from lags
where prev_date is not null
order by user_col asc, date_col desc

Dbfiddle here. Dbfiddle在这里。

Please for the next time, provide sample input as CTE (with clause) directly in question.请在下次直接提供示例输入作为 CTE(带子句)。

SQL does not have the concept of LAG baked in and SAS SQL does not implement windowed functions or CTEs SQL 没有 LAG 的概念,并且 SAS SQL 没有实现窗口函数或 CTE

The result set you want can be obtained using a reflexive join and SAS SQL automatic remerge feature.可以使用自反连接和 SAS SQL 自动重新合并功能获得所需的结果集。

data have;
attrib
  user length=$8
  date length= 8 format=yymmdd10. informat=yymmdd10.
;
input USER DATE;
datalines;
User1    20200516
User1    20200513
User1    20200501
User2    20200515
User2    20200511
;

proc sql;
  create table want as
  select 
    LEFT.user
  , LEFT.date
  , RIGHT.date as PREV_DATE
  , LEFT.date - RIGHT.date as DIFF
  from
    have as LEFT
  left join
    have as RIGHT
  on
    LEFT.user = RIGHT.user
  where
    LEFT.date > RIGHT.date
  group by
    LEFT.date
  having
    DIFF = MIN(DIFF)
  order by
    LEFT.user, LEFT.date desc, RIGHT.date desc
  ; 

Here is a data step approach这是一个数据步骤方法

data have;
input USER $ DATE :anydtdte.;
format date yymmddn8.;
datalines;
User1 20200516
User1 20200513
User1 20200501
User2 20200515
User2 20200511
;

data want;
    merge have
          have(firstobs=2 rename=(date=prev_date user=_user));
    if user=_user;
    diff=date-prev_date;
    drop _:;
run;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM