【发布时间】:2021-05-03 22:34:06
【问题描述】:
这是我的桌子
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);
(创建于DB Fiddle)
我想找到一个触发事件名称的人(任何人)并检索该用户当天的所有记录。
| 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 |
这是我的代码:
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
在右表中,只有一条记录满足event_name 为B 的条件,即ID 为002 的用户。然后我将其与左表连接,条件是他们的user_ids相等,日期为2020-12-10,删除其他id不同的用户001,以及同一个人的事件发生在2020-12-10之外的记录。
一切正常。
然后我修改了我的代码以检查它是否会像我预期的那样运行(确实如此,请参阅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
在这种情况下,我只需按一个条件连接表并过滤该用户的日期以获得正确的记录。
我阅读了一些答案 here 和 here 和 here,其中大多数示例都以常量为条件,有些人说 join 会更快,而其他人则表示编译器将优化子句并因此提高速度会是一样的。
我想知道在我的情况下,第一个是否会更快?
有什么在线平台可以比较速度吗?
【问题讨论】:
-
并不是说它会更快,但我更喜欢使用
DATE(t_left.date_time)而不是SUBSTRING_INDEX(t_left.date_time, ' ', 1)来提取日期。 -
只有当您可以使用内连接而不是右连接时,这些查询与输入的功能相同,即如果右表永远不会有不匹配的行。您的 where 仅适用于具有非空左表日期的行,因此您可以只使用内部联接。正确加入的意义何在?如果您需要右连接,则您的第二个查询是错误的——并且性能没有实际意义。 PS请:在询问和反映研究之前进行研究。在询问 SQL 性能之前,先研究它并研究询问它。 PS请把所有需要问的东西都放在你的帖子中,而不仅仅是一个小提琴。
-
@philipxy 感谢您的建议。我 8 年前学习了 SQL,并且刚刚开始使用它。其他地方的答案让我不知所措。
-
*请改写为使用
LEFT JOIN而不是RIGHT JOIN。) -
@RickJames 好的,让我看看。谢谢。
标签: mysql where-clause outer-join right-join