2017-09-07 107 views
0

我試圖在mySQL中完成某些工作,由於缺乏「滯後」功能以及因爲所有關於日期差異的示例,因此很難實現,因爲在所有這些例子總是有一個ID到一個日期。在這裏,我試圖在一個ID內做日期差異,並且當日期差異超過60時,然後返回1的指示符,否則爲0.在一個ID內減去多個日期

不知道最好的方法是怎麼去做這件事。是否將row_number()與日期結合使用?這個障礙是在多個ID內完成的,因爲我讀過的很多東西都沒有涵蓋。任何方向都會有幫助。 謝謝!

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

不能與MySQL使用行號無論是。 –

+0

使用用戶變量保存上一行的日期,然後使用'DATEDIFF(service_date,@previous_date)'來獲得差異。 – Barmar

+0

您還需要一個用於以前的ID的變量。當ID改變時,你重新開始。 – Barmar

回答

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

該OP想要一個滾動的差異,而不是從第一個差異。 – fyrye

+0

請記住,如果我簡化你的答案? – fyrye

+0

如果您添加自己的答案(可選地指出簡化),它會讓我更不迷惑,並教育我更多!如果您想減少視圖的數量,我故意將它們分開,以便於閱讀/理解。 – tpdi

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 
1

發佈,以簡化和糾正功能由@tpdi提供的接聽電話。請接受/ upvote他們的答案,因爲這是非常複製它。

的變化:

  • date_diff到DATEDIFF
  • 除去創建視圖呼叫贊成t子查詢的
  • 分配變量涉及diff值的0初始值
  • 指示符0 diff來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   | 
+1

很好地完成。害怕我最近沒有做過Mysql,所以select中的變量對我來說是新的!謝謝! – tpdi

+0

@tpdi謝謝,我喜歡你使用'MAX'和'COALESCE',我寫的答案是以類似的方式使用'JOIN',但是決定你是一個更好的方法。 – fyrye