+-----+------------+------------+---------------------+
| id  | seller_id  | prod_id    | date                |
+-----+------------+----------------------------------+
|   1 | 283        | 4243       | 2016-10-10 23:55:01 |
|   2 | 287        | 4243       | 2016-10-10 02:01:06 |
|   3 | 283        | 4243       | 2016-10-11 23:55:06 |
|   4 | 311        | 4243       | 2016-10-11 23:55:07 |
|   5 | 283        | 4243       | 2016-10-12 23:55:07 |
|   6 | 283        | 4243       | 2016-10-13 23:55:07 |
|   7 | 311        | 4243       | 2016-10-13 23:55:07 |
|   8 | 287        | 4243       | 2016-10-14 23:57:06 |
|   9 | 311        | 4243       | 2016-10-14 23:57:06 |
|  10 | 311        | 4243       | 2016-10-15 23:57:06 |
+-----+------------+------------+---------------------+


从上面的表格中,我将如何使用MySQL查询提取以下信息?

+------------+---------+----------------+---------------+
| seller_id  | prod_id | streak in days | begin streak  |
+-----+------------+--------------------+---------------+
| 283        | 4243    | 4              | 2016-10-10    |
| 287        | 4243    | 1              | 2016-10-10    |
| 311        | 4243    | 1              | 2016-10-11    |
| 311        | 4243    | 3              | 2016-10-13    |
| 287        | 4243    | 1              | 2016-10-14    |
+------------+---------+----------------+---------------|


因此,基本上,我需要为销售产品(prod_id)的每个卖家(seller_id)识别出连续日期的每个区域。

我将此示例限制为1个prod_id,并且只能使用几天,但是卖家确实销售了1种以上的产品(prod_id)

最佳答案

SELECT
  seller_id
  ,prod_id
  ,COUNT(*) as StreakInDays
  ,MIN(DateCol) as BeginStreak
FROM
  (
    SELECT
      seller_id
      ,prod_id
      ,DATE(DateCol) as DateCol
      ,(@rn:= if((@seller = seller_id) AND (@prod = prod_id), @rn + 1,
                 if((@seller:= seller_id) AND (@prod:= prod_id), 1, 1)
                  )
        ) as RowNumber
    FROM
      Transact t
      CROSS JOIN (SELECT @seller:=0, @prod:=0, @rn:=0) var
    ORDER BY
      seller_id
      ,prod_id
      ,DATE(DateCol)
    ) t
GROUP BY
  seller_id
  ,prod_id
  ,DATE_SUB(DateCol, INTERVAL RowNumber Day)
ORDER BY
  prod_id
  ,DATE_SUB(DateCol, INTERVAL RowNumber Day)
  ,seller_id


生成一个由seller_id和prod_id划分的分区行号。然后将Date-RownNumber用作分组,您可以通过简单的汇总获得答案。

SQL Fiddle向您展示它适用于多种产品,销售商等。http://sqlfiddle.com/#!9/0a0c44/8/0

请注意,如果同一位卖家在同一天可能对某笔商品进行的交易超过1笔,那么您需要在生成行号(如这个:

SELECT
  seller_id
  ,prod_id
  ,COUNT(*) as StreakInDays
  ,MIN(DateCol) as BeginStreak
FROM
  (
    SELECT
      seller_id
      ,prod_id
      ,DateCol
      ,(@rn:= if((@seller = seller_id) AND (@prod = prod_id), @rn + 1,
                 if((@seller:= seller_id) AND (@prod:= prod_id), 1, 1)
                  )
        ) as RowNumber
    FROM
     (SELECT DISTINCT seller_id, prod_id, DATE(DateCol) as DateCol
       FROM
         Transact
      )t
      CROSS JOIN (SELECT @seller:=0, @prod:=0, @rn:=0) var
    ORDER BY
      seller_id
      ,prod_id
      ,DateCol
    ) t
GROUP BY
  seller_id
  ,prod_id
  ,DATE_SUB(DateCol, INTERVAL RowNumber Day)
ORDER BY
  prod_id
  ,DATE_SUB(DateCol, INTERVAL RowNumber Day)
  ,seller_id


http://sqlfiddle.com/#!9/0a0c44/11

07-24 09:37