MySQL计数/跟踪条纹或连续日期
从上表中,我将如何使用MySQL查询提取以下信息MySQL计数/跟踪条纹或连续日期,mysql,sql,date,Mysql,Sql,Date,从上表中,我将如何使用MySQL查询提取以下信息 +-----+------------+------------+---------------------+ | id | seller_id | prod_id | date | +-----+------------+----------------------------------+ | 1 | 283 | 4243 | 2016-10-10 23:55:01 | |
+-----+------------+------------+---------------------+
| 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 |
+-----+------------+------------+---------------------+
因此,基本上我需要确定每个卖家(卖家id)销售产品(产品id)的每个连续日期块
我将此示例限制为1个prod_id,并且仅在几天内有效,但卖家确实销售了1个以上的产品(prod_id)
生成一个按卖方id和产品id划分的分区行号。然后使用日期-行号作为分组,您可以通过简单的聚合得到答案
SQL Fiddle向您展示它适用于多个产品、销售商等
注意:如果同一卖家可能在同一天拥有一个以上的产品交易,那么在生成行编号之前,您将需要使用具有不同卖家id、产品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
生成一个按卖方id和产品id划分的分区行号。然后使用日期-行号作为分组,您可以通过简单的聚合得到答案
SQL Fiddle向您展示它适用于多个产品、销售商等
注意:如果同一卖家可能在同一天拥有一个以上的产品交易,那么在生成行编号之前,您将需要使用具有不同卖家id、产品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
谢谢!正是我想要的。不过,我有一个小问题,这会打乱计数,即:有时某个卖家id/产品id组合在一天内有多个条目。我只希望每天计数1次,同一天的其他条目应视为重复条目,应忽略。我相信“DISTINCT”应该能够实现这一点,但我不确定如何实现。他们应该使用一组具有派生表的代码(选择DISTINCT seller…)来处理这种情况。基本上,您不需要直接在表上生成行号,而是需要在派生表上生成行号,这样可以消除重复项。如果我的答案对你有用,请投票并接受它,这样别人就会知道你得到了你需要的。谢谢Matt在产品id可以使用和更新(产品状态)时遇到问题。我试图通过向查询中的if语句添加prod_cond来解决这个问题,但仍然无法正常工作。当1个产品id列出新产品和1个已使用产品时,条纹被打破。这里的示例:@dean2020我不完全确定添加prod_-cond的目的是什么?是否要忽略prod_-cond中的更改?如果是,请按照派生表的顺序在DateCol之前添加prod_-cond。在你想打破连胜,然后同样的事情,你将需要改变的顺序,并考虑到datetime,但这将意味着你不会被聚集的日子,所以你需要使用日期差异的最大值和最小值的每个组,所以你应该创建一个组行号,使之容易。谢谢!正是我想要的。不过,我有一个小问题,这会打乱计数,即:有时某个卖家id/产品id组合在一天内有多个条目。我只希望每天计数1次,同一天的其他条目应视为重复条目,应忽略。我相信“DISTINCT”应该能够实现这一点,但我不确定如何实现。他们应该使用一组具有派生表的代码(选择DISTINCT seller…)来处理这种情况。基本上,您不需要直接在表上生成行号,而是需要在派生表上生成行号,这样可以消除重复项。如果我的答案对你有用,请投票并接受它,这样别人就会知道你得到了你需要的。谢谢Matt在产品id可以使用和更新(产品状态)时遇到问题。我试图通过向查询中的if语句添加prod_cond来解决这个问题,但仍然无法正常工作。当1个产品id列出新产品和1个已使用产品时,条纹被打破。这里的示例:@dean2020我不完全确定添加prod_-cond的目的是什么?是否要忽略prod_-cond中的更改?如果是,请按照派生表的顺序在DateCol之前添加prod_-cond。在你想打破连胜,然后同样的事情,你将需要改变的顺序,并考虑到datetime,但这将意味着你不会聚集在一天,所以你需要使用日期差异的最大值和最小值的每个组,所以你应该创建一个组行号,使之容易。
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