Here is my table
CREATE TABLE log_table (
`user_id` VARCHAR(5),
`date_time` DATETIME,
`event_name` VARCHAR(10),
`trivial` int
);
INSERT INTO log_table
(`user_id`, `date_time`, `event_name`, `trivial`)
VALUES
('001', '2020-12-10 10:00:02', 'c', 3),
('001', '2020-12-10 10:00:01', 'b', 9),
('001', '2020-12-10 10:00:40', 'e', 2),
('001', '2020-12-10 10:00:20', 'd', 6),
('001', '2020-12-10 10:00:00', 'a', 1),
('002', '2020-12-09 10:00:10', 'C', 9),
('002', '2020-12-10 10:00:50', 'D', 0),
('002', '2020-12-10 10:00:02', 'A', 2),
('002', '2020-12-10 10:00:09', 'B', 4);
(created at DB Fiddle )
I want to find one person(anyone) that triggered an event name and retrieve all the records of that user on that day.
user_id | date_time | event_name | trivial | trivial_new |
---|---|---|---|---|
001 | 2020-12-10 10:00:00 | a | 1 | 13 |
001 | 2020-12-10 10:00:01 | b | 9 | 19 |
001 | 2020-12-10 10:00:02 | c | 3 | 21 |
001 | 2020-12-10 10:00:20 | d | 6 | 20 |
001 | 2020-12-10 10:00:40 | e | 2 | 11 |
002 | 2020-12-09 10:00:02 | A | 2 | 15 |
002 | 2020-12-10 10:00:09 | B | 4 | 15 |
002 | 2020-12-10 10:00:10 | C | 9 | 15 |
002 | 2020-12-10 10:00:50 | D | 0 | 13 |
Here is my code:
SELECT t_left.*
FROM log_table AS t_left
RIGHT JOIN (SELECT user_id,
date_time
FROM log_table
WHERE BINARY event_name = 'B'
LIMIT 1) AS t_right
ON t_left.user_id = t_right.user_id
AND Substring_index(t_left.date_time, ' ', 1) =
Substring_index(t_right.date_time, ' ', 1)
ORDER BY date_time
In the right table, there would be only one record that satisfies the conditions that the event_name
is B
, that is the user with the id 002. And then I join it with the left table on conditions that their user_ids are equal and the date is 2020-12-10
, removing other users with different ids, 001
, and the records of the same person whose events occurred not on 2020-12-10
.
It works all well.
Then I modified my code to check if it would go as I expected to(it did, see here ):
SELECT t_left.*
FROM log_table AS t_left
RIGHT JOIN (SELECT user_id,
date_time
FROM log_table
WHERE BINARY event_name = 'B'
LIMIT 1) AS t_right
ON t_left.user_id = t_right.user_id
WHERE Substring_index(t_left.date_time, ' ', 1) =
Substring_index(t_right.date_time, ' ', 1)
ORDER BY date_time
In this case, I just join the tables by one condition and filter the dates of that user to get the right records.
I read some answers here and here and here where most of the examples are conditioning on a constant and some people say join would be faster while others state that the compiler will optimize the clauses and hence the speed would be the same.
I wonder if in my case the first one would be faster?
Any online platform to compare the speed?
ON
should be used to say how the tables are related.
WHERE
should be used for filtering.
For plain JOIN
( INNER JOIN
), they are implemented identically.
For LEFT/RIGHT, they may make a big difference.
If the second query is suppose to be the final query structure, you don't need to use RIGHT JOIN
anymore, that's especially true since you're matching the dates in WHERE
instead in ON
.. effectively cancelling the right join (or left join). Actually, since you're doing right join to a sub-query that only extract a certain data for the table on the right, there's hardly any reason to right join, you'll got more differences in results if you do left join instead. Besides, In my experience, JOIN
( INNER JOIN
) is usually much faster than left/right join.
Another thing is, indexes make a lot of differences when it comes to performance. On your current example, there were no indexes so I recommend that you do that. I learned a lot about indexing from @Rick James' page here .
Here is a fiddle based on your example date consisting of your original attempt and few more:
RIGHT JOIN.. ON... AND
RIGHT JOIN.. ON... WHERE
LEFT JOIN.. ON... AND
LEFT JOIN.. ON... WHERE
EXPLAIN
before and after index.https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=1b244deb6fad0dda0bf4aaf701e6bac2
PS: In the fiddle, I changed the date extraction to use DATE()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.