2016-08-18 74 views
1

Merchant s,他們可以提交Claim s。找到每個對象的最長連續時間間隔

我需要找到最長的時間段,在此期間Merchant至少有一個索賠。因此,每個merchant_id的時間段(一天中的幾分之一,無論如何)。

所以,例如:

+-------------+-----------+----------------------+----------------------+ 
| merchant_id | claim_id |   from   |   to   | 
+-------------+-----------+----------------------+----------------------+ 
|   1 |  11 | 2016-08-15 12:00:00 | 2016-08-17 12:00:00 | 
|   1 |  22 | 2016-08-16 12:00:00 | 2016-08-18 12:00:00 | 
|   1 |  33 | 2016-08-19 12:00:00 | 2016-08-20 12:00:00 | 
|   2 |  66 | 2016-08-15 12:00:00 | 2016-08-17 12:00:00 | 
|   2 |  67 | 2016-08-18 12:00:00 | 2016-08-19 12:00:00 | 
+-------------+-----------+----------------------+----------------------+ 

merchant_id對於= 1這將是3天。

對於merchant_id = 2這將是2天。

我該怎麼做?

+0

你會如何定義有*至少1個開放要求*人? –

+0

如果一個商家有索賠 - 那麼我們可以在表中看到一個claim_id - 它有一個開放時間 - 打開和關閉時間 - 到 – Dennis

+0

這在MySQL中非常複雜,因爲它不支持CTE或窗口功能。 –

回答

2

在MySQL中單獨做這件事真的很複雜。我已經嘗試過特定merchant_id。我不確定這是不是100%沒有檢查不同的輸入集。

但是你可以嘗試一下,稍後我可以解釋背後的邏輯。

SELECT 
firstTable.merchant_id, 
MAX(TIMESTAMPDIFF(DAY,firstTable.from,secondTable.to)) AS maxConsecutiveDays 
FROM 
(
    SELECT 
    A.merchant_id, 
    A.from, 
    @rn1 := @rn1 + 1 AS row_number 
    FROM merchants A 
    CROSS JOIN (SELECT @rn1 := 0) var 
    WHERE A.merchant_id = 2 
    AND NOT EXISTS (
     SELECT 1 FROM merchants B WHERE B.merchant_id = A.merchant_id AND A.idt <> B.idt AND A.`from` BETWEEN B.from AND B.to 
    ) 
    ORDER BY A.from 
) AS firstTable 

INNER JOIN (

    SELECT 
    A.merchant_id, 
    A.to, 
    @rn2 := @rn2 + 1 AS row_number 
    FROM merchants A 
    CROSS JOIN (SELECT @rn2 := 0) var 
    WHERE A.merchant_id = 2 
    AND NOT EXISTS (
     SELECT 1 FROM merchants B WHERE B.merchant_id = A.merchant_id AND A.idt <> B.idt AND A.to BETWEEN B.from AND B.to 
    ) 
    ORDER BY A.to 
) AS secondTable 
ON firstTable.row_number = secondTable.row_number; 

WORKING DEMO

算法:

讓我們考慮以下步驟特定merchant_id

  1. 首先查找不裏面的所有的起點任何的 範圍。我稱之爲獨立起點。假設這些開始點 存儲在一個集合S
  2. 第二個現在找到所有不在 範圍內的終點。這些是獨立的終點,並存儲在一組 E
  3. 按照時間的升序對組進行排序。
  4. 現在給出從1開始的集合中的每個元素的排名。
  5. 在匹配的排名數字上加入這兩組。
  6. 現在列舉兩套同時獲得 天的差異。然後找到這個差異的最大值。

最後一步可以通過下面的代碼段來說明:


int maxDiff = 0; 

for(int i=0; i< E.size(); i++){ 
    if((E.get(i) - S.get(i) > maxDiff){ 
    maxDiff = E.get(i) - S.get(i); 
    } 
} 

而且maxDiff是你的輸出;

編輯:

爲了獲得連續的最長天每個商家檢查這個DEMO

+0

哇!非常感謝。需要一個清晨,一杯濃郁的咖啡和清新的頭腦,才能真正瞭解它。謝謝! – Dennis

+0

當然。慢慢來。 :) @丹尼斯 – 1000111