在一个ID

时间:2017-09-07 22:55:57

标签: mysql sql date datediff

我试图在mySQL中完成一些事情,由于缺乏"滞后"函数,因为我已经阅读了有关日期差异的所有示例,因为在所有这些示例中,始终有一个ID到一个日期。在这里,我试图在ID中进行日期差异,当日期差异超过60时,则返回指标1,否则为0.

不确定最好的办法是什么。是否将row_number()与日期结合使用?这个障碍是在多个身份证中进行的,因为我读到的很多内容都没有涵盖。任何方向都会有所帮助。 谢谢!

ID  |   Service Date    |   Date Difference |   Indicator
1   |   1/22/2016       |   0               |   1
1   |   3/26/2016       |   64              |   1
1   |   5/25/2016       |   60              |   0
1   |   9/15/2016       |   113             |   1
2   |   8/1/2016        |   0               |   1
3   |   1/26/2016       |   0               |   1
3   |   3/9/2016        |   43              |   0
3   |   4/30/2016       |   52              |   0
4   |   8/9/2016        |   0               |   1
5   |   11/19/2016      |   0               |   1
6   |   10/14/2016      |   0               |   1
7   |   1/31/2016       |   0               |   1
7   |   8/11/2016       |   193             |   1

3 个答案:

答案 0 :(得分:1)

create view id_and_date as 
select id, service_date from your table;

create view id_and_date_and_prior as 
select 
a.id, a.service_date, 
coalesce(
  (select max(b.service_date) from id_and_date b 
    where b.id = a.id and b.service_date < a.service_date), 
 a.service_date)
as prior_date
from id_and_date a

select a.id, a.service_date, a.prior_date
date_diff(a.service_date, a.prior_date) as diff, 
case when date_diff(a.service_date, a.prior_date) > 60 
  then 1 else 0 end 
as indicator
from id_and_date_and_prior a

答案 1 :(得分:1)

您可以使用变量,但这很棘手。为了使其可靠地工作,需要在单个表达式中分配所有变量:

select t.*, datediff(prev_date, date) as diff,
       (case when datediff(prev_date, date) < 60 then 0 else 1 end) as indicator
from (select t.*,
             (case when @id = id
                   then (case when (@prev := @d) = NULL then 'never' -- intentional
                              when (@d := date) = NULL then 'never' -- intentional
                              else @prev
                         end)
                   when (@d := date) = NULL then 'never' -- intentional
                   else NULL
              end) as prev_date
      from t cross join
           (select @id := -1, @d := '') params
      order by id, date
     ) t

答案 2 :(得分:1)

发布以简化和更正@tpdi提供的答案中的函数调用。请接受/ upvote他们的答案,因为这几乎是从它复制。

的变化:

  • date_diff至DATEDIFF
  • 删除了创建视图调用,转而使用t
  • 子查询
  • 将变量赋值给diff值
  • 初始值为0的指标为0差异为1
  • 在有利于IF的情况下取代
SELECT 
c.id, 
c.service_date, 
@diff := DATEDIFF(c.service_date, c.prior_date) AS diff, 
IF(@diff = 0 || @diff > 60, 1, 0) AS indicator
FROM (
    SELECT 
    a.id, 
    a.service_date, 
    COALESCE(
        (SELECT MAX(b.service_date) 
        FROM t AS b 
        WHERE b.id = a.id 
        AND b.service_date < a.service_date),
        a.service_date
    ) AS prior_date
    FROM t AS a
) AS c;

将导致:

| id | service_date | diff | indicator |
| 1  | 2016-01-22   | 0    | 1         |
| 1  | 2016-03-26   | 64   | 1         |
| 1  | 2016-05-25   | 60   | 0         |
| 1  | 2016-09-15   | 113  | 1         |
| 2  | 2016-08-01   | 0    | 1         |
| 3  | 2016-01-26   | 0    | 1         |
| 3  | 2016-03-09   | 43   | 0         |
| 3  | 2016-04-30   | 52   | 0         |
| 4  | 2016-08-09   | 0    | 1         |
| 5  | 2016-11-19   | 0    | 1         |
| 6  | 2016-10-14   | 0    | 1         |
| 7  | 2016-01-31   | 0    | 1         |
| 7  | 2016-08-11   | 193  | 1         |