表 payment_transaction
+----+---------+--------+------------+
| ID | user_id | status | time_stamp |
+----+---------+--------+------------+
| 1 | 1 | 1 | 1414541884 |
| 2 | 2 | 0 | 1414576722 |
| 3 | 2 | 0 | 1414577273 |
| 4 | 3 | 0 | 1414782966 |
| 5 | 3 | 1 | 1414785691 |
| 6 | 4 | 0 | 1415112933 |
+----+---------+--------+------------+
该表存储所有付款交易。 status = 0
表示无论何种原因支付失败,status = 1
表示支付成功。
我现在想设置一个 cronjob,所有在过去 7 天内无法购买成员(member)资格的用户都会收到一条消息。如上面的示例表所示,我只需要 2 行,其中包含最近付款的 user_id
、transaction_id
和最近付款的 time_stampe
。由于user_id = 3
在第一次付款失败后成功获得成员(member)资格,因此他应该被排除在外:
+---------+----------------+------------+
| user_id | transaction_id | time_stamp |
+---------+----------------+------------+
| 2 | 3 | 1414577273 |
| 4 | 6 | 1415112933 |
+---------+----------------+------------+
是否可以在一个查询中完成所有这些工作?如果是,它比使用两个查询更有效吗?
到目前为止我所得到的:
SELECT DISTINCT
`t`.`user_id`,
`t`.`id` AS `transaction_id`,
`t`.`time_stamp`
FROM `payment_transaction` AS `t`
WHERE
`t`.`status` = 0
AND `t`.`time_stamp` < UNIX_TIMESTAMP() - 60*60*24*7
ORDER BY
`t`.`id`
但是,它并没有排除 user_id = 3
的用户,并且还为我提供了第一次失败的付款,而不是最近一次。
---- 编辑 ----
感谢 RST 在下面的评论中提供了解决方案。经过一些额外的更改后,最终查询如下所示:
SELECT
`t`.`user_id`,
MAX(`t`.`id`) AS `transaction_id`,
MAX(`t`.`time_stamp`) AS `time_stamp`
FROM `payment_transaction` AS `t`
WHERE
`t`.`status` = 0
AND `t`.`time_stamp` < UNIX_TIMESTAMP() - 60*60*24*7
AND `t`.`user_id` NOT IN (
SELECT `user_id`
FROM `payment_transaction`
WHERE `status` = 1
AND UNIX_TIMESTAMP(`time_stamp`) < UNIX_TIMESTAMP() - 60*60*24*7
)
GROUP BY
`t`.`user_id`
ORDER BY
`t`.`id`
最佳答案
稍微偏离您的请求,但仍然应该得到相同的结果,具体取决于您对应用程序进行编码的方式。最新交易最相关的假设是否准确?
如果是这样,您可以查看如下内容(未经测试):
SELECT DISTINCT
`t`.`user_id`,
`t`.`id` AS `transaction_id`,
`t`.`time_stamp`
FROM `payment_transaction` AS `t`
WHERE
`t`.`time_stamp` < UNIX_TIMESTAMP() - 60*60*24*7
GROUP BY
`t`.`user_id`
ORDER BY
`t`.`id`
请注意,我尚未测试此 SQL,因为我不在我的开发机器上。我建议您仔细查看 GROUP BY 命令的复杂性,以确保不会出现一些未捕获的边缘情况。
关于php - MySQL:获取特定时间范围内值为 0 的所有条目,除非同一时间范围内存在值为 1 的条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26754409/