找到每个对象最长的连续时间间隔

时间:2016-08-18 15:49:08

标签: mysql sql

Merchant个,他们可以提交Claim个。

我需要找到Merchant至少有1个声明的最长时间段。所以每个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天。

我该怎么做?

1 个答案:

答案 0 :(得分: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. 现在同时枚举两组并获得差异 天。后来找到了这种差异的最大值。
  7. 最后一步可以通过以下代码片段来说明:

    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