MYSQL:连续日期的表更新

标签 mysql sql gaps-and-islands

大家晚上好

我整天都在和这个问题搏斗。

我正在尝试更新我的客户表中的一列,该列将显示他们成为订阅者的次数。这个表是从一个大数据转储创建的,每个客户都有单独的行,每个月他们都是订阅者(每个月分配一个迭代数字)。名字是独一无二的。它看起来像这样并表明(例如)Jane Doe 是期间 1000 的订阅者,但不是期间 1002 的订阅者。

Row_ID Customer_Name  Date_Code 
1      Jane Doe       1000      
2      Jane Doe       1001      
3      Jane Doe       1004      
4      Jane Doe       1005      
5      Ted Jones      1000      
6      Ted Jones      1001      
7      Ted Jones      1002      
etc...

在这种情况下,Jane Doe 是 1000-1001 的订阅者,离开我们的订阅,然后从 1004-1005 回来。我有一个包含所有日期逻辑(开始日期、结束日期、日期代码等)的主表。它看起来大致是这样的:

Start_Date   End_Date    Date_Code
1990-01-01   1990-03-31  1000
1990-04-01   1990-06-30  1001
1990-07-01   1990-09-30  1002
1990-10-01   1990-12-31  1003
etc...

我正试图找到一种方法使输出类似于:

Customer_Name  Subscription_Count
Jane Doe       2
Ted Jones      1

有没有人遇到过这样的事情?对我来说(作为一个人)很明显数字是(或不)连续的并且是(或不是)整个样本的表示,但我不确定如何让 MYSQL 理解它。我很感激任何想法。

*编辑 - 我尝试了 Join 和 Where Not Exists 两种替代方法,但都在 10 分钟后超时。我相信这是由于主表的大小(~100,000 行)。你有什么建议吗?再次感谢所有评论。

**编辑 #2 - 添加索引并稍微调整我的表后,两种解决方案都很好用。再次感谢您对解决这个问题的支持。

最佳答案

查询可能看起来像这样:

SELECT customer_name, count(*) AS subscriptions
FROM   tbl AS t
WHERE NOT EXISTS (
    SELECT *
    FROM tbl AS t1
    WHERE t1.customer_name = t.customer_name
    AND t1.date_code = t.date_code + 1
    )
GROUP BY customer_name;

这里的技巧是排除所有行,但每个客户的 date_code 系列中只有一个行,然后计数:每个 block 只有最后一行没有后继行(date_code + 1)。

我假设连续的 date_codes 形成一个订阅(根据我对问题的第一条评论)。因此,有关 Start_Date 的附加信息和 End_Date不需要。


性能

LEFT JOIN / IS NULL 实际上应该比 NOT EXISTS 快一点在 MySQL 中(由@nnichols 提供)。
对于性能来说更重要的是索引。为了加快速度,您需要在 customer_name 上建立索引和 date_code .像这样:

CREATE INDEX tbl_customer_name ON tbl(customer_name);
CREATE INDEX tbl_date_code ON tbl(date_code);

关于MYSQL:连续日期的表更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9651730/

相关文章:

php - 在php中管理用户权限

php - 用多维数组垂直填充 HTML 表

mysql - 具有多个 IS NULL 条件的 CASE WHEN 语句

SQL : built-in way to detect gaps in a arbitrary series of dates?

mysql - 从两个不同的表计算百分比

php - SELECT WHERE 变量不起作用

sql - ActiveRecord has_many 通过多态 has_many

mysql - 两个表计入两个单独的列

mysql - 创建查询以获取未完成调用的计数