如何只取最后一笔交易来计算 timediff mysql 5.7
how to take only last transaction to count timediff mysql 5.7
这是
的后续问题
这是我的 fiddle
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=31b3be9d1e2444eb0b32c262176aa4b4
我有这个table
CREATE TABLE test (
ID INT,
user_id INT,
createdAt DATE,
status_id INT
);
INSERT INTO test VALUES
(1, 13, '2020-01-01', 8),
(2, 13, '2020-01-03', 8),
(3, 13, '2020-01-06', 8),
(4, 13, '2020-01-02', 7),
(5, 13, '2020-01-03', 7),
(6, 14, '2020-03-03', 8),
(7, 13, '2020-03-04', 4),
(8, 15, '2020-04-04', 7),
(9, 14, '2020-03-02', 6),
(10, 14, '2020-03-10', 5),
(11, 13, '2020-04-10', 8);
select * from test where status_id != 7
order by createdAt;
+----+---------+------------+-----------+
| ID | user_id | createdAt | status_id |
+----+---------+------------+-----------+
| 1 | 13 | 2020-01-01 | 8 |
| 2 | 13 | 2020-01-03 | 8 |
| 3 | 13 | 2020-01-06 | 8 |
| 9 | 14 | 2020-03-02 | 6 |
| 6 | 14 | 2020-03-03 | 8 |
| 7 | 13 | 2020-03-04 | 4 |
| 10 | 14 | 2020-03-10 | 5 |
+----+---------+------------+-----------+
id是交易的id,user_Id是进行交易的用户的id,createdAt是交易发生的日期,status_id是交易的状态(如果status_Id为7,则交易被拒绝或不批准。
所以在这种情况下,我想找出在“2020-02-01”到“2020-04-01”之间的时间范围内每个重复用户的每笔批准交易的时间差,重复用户是用户谁在时间范围结束前进行交易,并且至少在该时间范围内再次进行 1 次交易,在这种情况下,用户在 '2020-04-01' 之前进行批准交易并且至少再次进行 1 次批准交易在“2020-02-01”和“2020-04-01”之间。
对于这个问题,我根据@Akina
的回答使用了这个查询
-- Get pairs (current transaction, previous transaction) for these users
SELECT t1.user_id,
t1.createdAt,
t2.createdAt,
DATEDIFF(t2.createdAt, t1.createdAt) diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id
AND t1.createdAt < t2.createdAt
AND 7 NOT IN (t1.status_id, t2.status_id)
-- get data only for users from prev. query
JOIN (SELECT t3.user_id
FROM test t3
WHERE t3.status_id != 7
GROUP BY t3.user_id
HAVING SUM(t3.createdAt < '2020-04-01') > 1
AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
-- check that there is no approved transaction between selected transactions
WHERE NOT EXISTS (SELECT NULL
FROM test t5
WHERE t1.user_id = t5.user_id
AND t5.status_id != 7
AND t1.createdAt < t5.createdAt
AND t5.createdAt < t2.createdAt)
the output table was like this
+----------+------------+------------+------+
| user_id | createdAt | createdAt | diff |
+----------+------------+------------+------+
| 13 | 2020-01-01 | 2020-01-03 | 2 |
| 13 | 2020-01-03 | 2020-01-06 | 3 |
| 14 | 2020-03-02 | 2020-03-03 | 1 |
| 13 | 2020-01-06 | 2020-03-04 | 58 |
| 14 | 2020-03-03 | 2020-03-10 | 7 |
+----------+------------+------------+------+
问题是,此查询计算每个用户在时间范围('2020-02-01' 到 '2020-04-01')中的时间差,并且也在时间范围之前计算时间差(请参阅 users_id 13,用户还计算日期'2020-01-01'到'2020-01-03'之间的时差)。我想要的是,如果用户在时间范围之前有一笔交易,我只想计算他的 users_id 时间范围之前的最后一笔交易(在这种情况下,users_id 13 我只想计算时差在 '2020-01-06' 到 '2020-03-04' 因为 2020 年 1 月 6 日是用户在时间范围之前最后一次交易的日期。所以在这种情况下,预期结果是这样的:
+---------+------------+------------+------+
| user_id | createdAt | createdAt | diff |
+---------+------------+------------+------+
| 14 | 2020-03-02 | 2020-03-03 | 1 |
| 13 | 2020-01-06 | 2020-03-04 | 58 |
| 14 | 2020-03-03 | 2020-03-10 | 7 |
+---------+------------+------------+------+
我认为您只需排除在时间范围 BETWEEN '2020-02-01' AND '2020-04-01
开始之前结束的每笔交易,因为他们不感兴趣。
因为您已经排除了超出时间范围的所有内容
您仍然知道何时在事务开始和结束时输入数据,因此您应该将属于一起的行标记在一个额外的列中,这将使您的查询更简单,除了您的状态不可用, 因为它会重复自己
SELECT t1.user_id,
t1.createdAt,
t2.createdAt createcompare,
DATEDIFF(t2.createdAt, t1.createdAt) diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id
AND t1.createdAt < t2.createdAt
AND 7 NOT IN (t1.status_id, t2.status_id)
JOIN (SELECT t3.user_id
FROM test t3
WHERE t3.status_id != 7
GROUP BY t3.user_id
HAVING SUM(t3.createdAt < '2020-04-01') > 1
AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
WHERE NOT EXISTS (SELECT NULL
FROM test t5
WHERE t1.user_id = t5.user_id
AND t5.status_id != 7
AND t1.createdAt < t5.createdAt
AND t5.createdAt < t2.createdAt)
HAViNG createcompare > '2020-02-01'
user_id | createdAt | cretecompare | diff
------: | :--------- | :----------- | ---:
14 | 2020-03-02 | 2020-03-03 | 1
13 | 2020-01-06 | 2020-03-04 | 58
14 | 2020-03-03 | 2020-03-10 | 7
13 | 2020-03-04 | 2020-04-10 | 37
db<>fiddle here
更新:
现在这实际上更有意义
SELECT t1.user_id,
t1.createdAt cretecompare1,
t2.createdAt cretecompare2,
DATEDIFF(t2.createdAt, t1.createdAt) diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id
AND t1.createdAt < t2.createdAt
AND 7 NOT IN (t1.status_id, t2.status_id)
JOIN (SELECT t3.user_id
FROM test t3
WHERE t3.status_id != 7
GROUP BY t3.user_id
HAVING SUM(t3.createdAt < '2020-04-01') > 1
AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
WHERE NOT EXISTS (SELECT NULL
FROM test t5
WHERE t1.user_id = t5.user_id
AND t5.status_id != 7
AND t1.createdAt < t5.createdAt
AND t5.createdAt < t2.createdAt)
HAViNG cretecompare2 BETWEEN '2020-02-01' AND '2020-04-01'
user_id | cretecompare1 | cretecompare2 | diff
------: | :------------ | :------------ | ---:
14 | 2020-03-02 | 2020-03-03 | 1
13 | 2020-01-06 | 2020-03-04 | 58
14 | 2020-03-03 | 2020-03-10 | 7
db<>fiddle here
这是
这是我的 fiddle https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=31b3be9d1e2444eb0b32c262176aa4b4
我有这个table
CREATE TABLE test (
ID INT,
user_id INT,
createdAt DATE,
status_id INT
);
INSERT INTO test VALUES
(1, 13, '2020-01-01', 8),
(2, 13, '2020-01-03', 8),
(3, 13, '2020-01-06', 8),
(4, 13, '2020-01-02', 7),
(5, 13, '2020-01-03', 7),
(6, 14, '2020-03-03', 8),
(7, 13, '2020-03-04', 4),
(8, 15, '2020-04-04', 7),
(9, 14, '2020-03-02', 6),
(10, 14, '2020-03-10', 5),
(11, 13, '2020-04-10', 8);
select * from test where status_id != 7
order by createdAt;
+----+---------+------------+-----------+
| ID | user_id | createdAt | status_id |
+----+---------+------------+-----------+
| 1 | 13 | 2020-01-01 | 8 |
| 2 | 13 | 2020-01-03 | 8 |
| 3 | 13 | 2020-01-06 | 8 |
| 9 | 14 | 2020-03-02 | 6 |
| 6 | 14 | 2020-03-03 | 8 |
| 7 | 13 | 2020-03-04 | 4 |
| 10 | 14 | 2020-03-10 | 5 |
+----+---------+------------+-----------+
id是交易的id,user_Id是进行交易的用户的id,createdAt是交易发生的日期,status_id是交易的状态(如果status_Id为7,则交易被拒绝或不批准。
所以在这种情况下,我想找出在“2020-02-01”到“2020-04-01”之间的时间范围内每个重复用户的每笔批准交易的时间差,重复用户是用户谁在时间范围结束前进行交易,并且至少在该时间范围内再次进行 1 次交易,在这种情况下,用户在 '2020-04-01' 之前进行批准交易并且至少再次进行 1 次批准交易在“2020-02-01”和“2020-04-01”之间。
对于这个问题,我根据@Akina
的回答使用了这个查询-- Get pairs (current transaction, previous transaction) for these users
SELECT t1.user_id,
t1.createdAt,
t2.createdAt,
DATEDIFF(t2.createdAt, t1.createdAt) diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id
AND t1.createdAt < t2.createdAt
AND 7 NOT IN (t1.status_id, t2.status_id)
-- get data only for users from prev. query
JOIN (SELECT t3.user_id
FROM test t3
WHERE t3.status_id != 7
GROUP BY t3.user_id
HAVING SUM(t3.createdAt < '2020-04-01') > 1
AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
-- check that there is no approved transaction between selected transactions
WHERE NOT EXISTS (SELECT NULL
FROM test t5
WHERE t1.user_id = t5.user_id
AND t5.status_id != 7
AND t1.createdAt < t5.createdAt
AND t5.createdAt < t2.createdAt)
the output table was like this
+----------+------------+------------+------+
| user_id | createdAt | createdAt | diff |
+----------+------------+------------+------+
| 13 | 2020-01-01 | 2020-01-03 | 2 |
| 13 | 2020-01-03 | 2020-01-06 | 3 |
| 14 | 2020-03-02 | 2020-03-03 | 1 |
| 13 | 2020-01-06 | 2020-03-04 | 58 |
| 14 | 2020-03-03 | 2020-03-10 | 7 |
+----------+------------+------------+------+
问题是,此查询计算每个用户在时间范围('2020-02-01' 到 '2020-04-01')中的时间差,并且也在时间范围之前计算时间差(请参阅 users_id 13,用户还计算日期'2020-01-01'到'2020-01-03'之间的时差)。我想要的是,如果用户在时间范围之前有一笔交易,我只想计算他的 users_id 时间范围之前的最后一笔交易(在这种情况下,users_id 13 我只想计算时差在 '2020-01-06' 到 '2020-03-04' 因为 2020 年 1 月 6 日是用户在时间范围之前最后一次交易的日期。所以在这种情况下,预期结果是这样的:
+---------+------------+------------+------+
| user_id | createdAt | createdAt | diff |
+---------+------------+------------+------+
| 14 | 2020-03-02 | 2020-03-03 | 1 |
| 13 | 2020-01-06 | 2020-03-04 | 58 |
| 14 | 2020-03-03 | 2020-03-10 | 7 |
+---------+------------+------------+------+
我认为您只需排除在时间范围 BETWEEN '2020-02-01' AND '2020-04-01
开始之前结束的每笔交易,因为他们不感兴趣。
因为您已经排除了超出时间范围的所有内容
您仍然知道何时在事务开始和结束时输入数据,因此您应该将属于一起的行标记在一个额外的列中,这将使您的查询更简单,除了您的状态不可用, 因为它会重复自己
SELECT t1.user_id, t1.createdAt, t2.createdAt createcompare, DATEDIFF(t2.createdAt, t1.createdAt) diff -- table for a transaction FROM test t1 -- table for prev. transaction JOIN test t2 ON t1.user_id = t2.user_id AND t1.createdAt < t2.createdAt AND 7 NOT IN (t1.status_id, t2.status_id) JOIN (SELECT t3.user_id FROM test t3 WHERE t3.status_id != 7 GROUP BY t3.user_id HAVING SUM(t3.createdAt < '2020-04-01') > 1 AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id WHERE NOT EXISTS (SELECT NULL FROM test t5 WHERE t1.user_id = t5.user_id AND t5.status_id != 7 AND t1.createdAt < t5.createdAt AND t5.createdAt < t2.createdAt) HAViNG createcompare > '2020-02-01'
user_id | createdAt | cretecompare | diff ------: | :--------- | :----------- | ---: 14 | 2020-03-02 | 2020-03-03 | 1 13 | 2020-01-06 | 2020-03-04 | 58 14 | 2020-03-03 | 2020-03-10 | 7 13 | 2020-03-04 | 2020-04-10 | 37
db<>fiddle here
更新:
现在这实际上更有意义
SELECT t1.user_id, t1.createdAt cretecompare1, t2.createdAt cretecompare2, DATEDIFF(t2.createdAt, t1.createdAt) diff -- table for a transaction FROM test t1 -- table for prev. transaction JOIN test t2 ON t1.user_id = t2.user_id AND t1.createdAt < t2.createdAt AND 7 NOT IN (t1.status_id, t2.status_id) JOIN (SELECT t3.user_id FROM test t3 WHERE t3.status_id != 7 GROUP BY t3.user_id HAVING SUM(t3.createdAt < '2020-04-01') > 1 AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id WHERE NOT EXISTS (SELECT NULL FROM test t5 WHERE t1.user_id = t5.user_id AND t5.status_id != 7 AND t1.createdAt < t5.createdAt AND t5.createdAt < t2.createdAt) HAViNG cretecompare2 BETWEEN '2020-02-01' AND '2020-04-01'
user_id | cretecompare1 | cretecompare2 | diff ------: | :------------ | :------------ | ---: 14 | 2020-03-02 | 2020-03-03 | 1 13 | 2020-01-06 | 2020-03-04 | 58 14 | 2020-03-03 | 2020-03-10 | 7
db<>fiddle here