假设我有以下交易数据:
+--------------------------------------------------+
| CustomerID | TransactionID | TransactionDate |
+--------------------------------------------------+
| 1 | 1 | 2015-01-22 15:09:43 |
| 1 | 2 | 2015-01-22 16:58:13 |
| 1 | 3 | 2015-01-23 07:05:53 |
| 2 | 4 | 2015-02-02 21:12:28 |
| 2 | 5 | 2015-02-02 22:01:59 |
| 3 | 6 | 2015-02-03 19:50:47 |
| 2 | 7 | 2015-02-04 16:12:08 |
| 4 | 8 | 2015-02-05 17:13:29 |
+--------------------------------------------------+
TransactionDate,BTW,存储为unix时间戳,而不是日期的字符串表示形式。我刚刚将其转换为更容易阅读。
我正在尝试制作一个查询,告诉我哪些客户(通过ID)在24小时内购买了3次或更多次。在这个(公认的基本)例子中,唯一满足该标准的客户是#1,因为这三个交易都发生在24小时内。客户#2不会,因为在24小时内只发生了两笔交易;第三个是在第一个24小时窗口之外。我关心的只是客户ID;我不需要知道涉及哪些交易或实际交易日期。目前我通过代码执行此操作 - 运行将上表返回到PHP数组的查询,使用以下代码转换结果:
foreach ($results as $result)
$data[$result['CustomerID']][] = array(
'TransactionID' => $result['TransactionID'],
'TransactionDate' => $result['TransactionDate']
);
...这给了我一个像这样的数组......
$data = array(
'1' => array(
array(
'TransactionID' => '1',
'TransactionDate' => '2015-01-22 15:09:43'
),
array(
'TransactionID' => '2',
'TransactionDate' => '2015-01-22 16:58:13'
),
array(
'TransactionID' => '3',
'TransactionDate' => '2015-01-23 07:05:53'
),
),
'2' => array(
array(
'TransactionID' => '4',
'TransactionDate' => '2015-02-02 21:12:28'
),
array(
'TransactionID' => '5',
'TransactionDate' => '2015-02-02 22:01:59'
),
array(
'TransactionID' => '7',
'TransactionDate' => '2015-02-04 16:12:08'
),
),
// etc.
)
...然后通过每个客户查看第三条记录是否在第一条记录的24小时内,第四条记录是否在第二条记录的24小时内,等等,具体取决于有多少购买记录是那个时期的客户。如果在任何时候我在24小时窗口内找到三条记录,我会标记该客户ID并转到下一条(我真的不在乎我发现了多少24小时3+交易,只是我找到了至少一个)。
如果它像8个交易记录一样简单,我会很高兴把它作为一些程序代码留下来,就像我在这里概述的那样;但是当我将92,000条记录从数据库传输到PHP进行处理时(每条记录更像是70个字段,而不是3个字段),我开始遇到严重的内存和超时问题。我知道,因为我以前曾经使用大型数据集(数百万行),任何值得盐的数据库服务器都可以比在Apache下作为模块运行的PHP快得多。我不知道的是如何直接在查询环境中计算记录之间的时间。这种处理在MySQL中是否可行?
答案 0 :(得分:0)
您可以尝试这样的事情:
SELECT frst.CustomerID, frst.TransactionDate as firstdate,
min(scnd.TransactionDate) as secdate,
min(third.TransactionDate) as thirddate FROM so29518803 frst
inner join so29518803 scnd on scnd.CustomerID = frst.CustomerID and
scnd.TransactionDate > frst.TransactionDate inner join so29518803 third on
scnd.CustomerID = third.CustomerID and
third.TransactionDate>scnd.TransactionDate group by frst.CustomerID,
frst.TransactionDate
having timestampdiff(second,firstdate, thirddate) < 86400
使用CustomerID和TransactionDate上的索引,查询运行得非常快。 但是,如果您需要在时间段内检查大量交易,则此方法将无效。