This is my table:
+------+--------+-------------------+
| user | item | date_time |
| 10 | 01 | 10-10-10 20:10:05 |
| 10 | 02 | 10-10-10 20:10:10 |
| 10 | 03 | 10-10-10 20:10:10 |
| 20 | 02 | 10-10-10 20:15:10 |
| 20 | 02 | 10-10-10 20:20:10 |
| 30 | 10 | 10-10-10 20:01:10 |
| 30 | 20 | 10-10-10 20:01:20 |
| 30 | 30 | 10-10-10 20:05:20 |
+------+--------+-------------------+
I want to do a query that return a user that took multiple items in a 1min interval, like this result:
+------+--------+-------------------+
| user | item | date_time |
| 10 | 01 | 10-10-10 20:10:05 |
| 10 | 02 | 10-10-10 20:10:10 |
| 10 | 03 | 10-10-10 20:10:10 |
| 30 | 10 | 10-10-10 20:01:10 |
| 30 | 20 | 10-10-10 20:01:20 |
+------+--------+-------------------+
How can I do this?
Edit
And if I want to only display users that appear 2 or more times on this output?
Example:
+------+--------+-------------------+
| user | item | date_time |
| 10 | 01 | 10-10-10 20:10:05 |
| 10 | 02 | 10-10-10 20:10:10 |
| 10 | 03 | 10-10-10 20:10:10 |
+-----开发者_开发百科-+--------+-------------------+
Yes, you need to add a primary key (id) as suggested by @Will.
To get each item once (and only once) regardless of how many matches there were within the 1-minute window, try a subquery instead of a full join:
Select user,item,date_time from my_table t1
where id in (select t2.id from my_table t2,my_table t3
where t2.id <> t3.id and t2.user = t3.user
and abs(t2.date_time - t3.date_time) < 60)
--edit-- For your edited question, that depends on exactly what you mean. Do you mean "users who bought 3 or more items within 60 seconds" or "users who appear more than 2 times in the output". The latter is easy to do: assume the results of the above query are saved in a temporary table (or view) "temp1":
select * from my_table where user in
(select user from temp1 group by user having count(*) > 2);
You'll have to join the table against itself (let's call the table aliases T1 and T2). Then write a WHERE clause to filter only rows where T1.user is equal T2.user and the absolute value of the difference between T1.date_time and T2.date_time is less than a minute.
But the problem is that every row will get selected, because you have no primary key on your table, thus there's no way to detect when a row is getting joined with itself. Create a primary key (an autonumber sequence will work just fine), and add a condition to the WHERE clause that says T1.id <> T2.id
.
So in (untested) code form:
SELECT *
FROM stuff T1, stuff T2
WHERE T1.user = T2.user
AND ABS(UNIX_TIMESTAMP(T1.date_time) - UNIX_TIMESTAMP(T2.date_time)) < 60
AND T1.id <> T2.id;
let's try that one:
SELECT * FROM myTable
JOIN (SELECT MAX(date_time) AS maxi, MIN(date_time) AS mini, user AS uid FROM myTable GROUP BY uid) AS otherTable
ON date_time<=maxi AND date_time>=mini AND user = uid AND UNIX_TIMESTAMP(maxi) - UNIX_TIMESTAMP(mini) < 60
GROUP BY uid, date_time
精彩评论