连接子句是实现这一点的唯一方法而 CTE 不能吗?
Are join clauses the only method to realize this and CTEs cannot?
这是我的 table(创建于 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
我从 What is a Common Table Expression? 那里学到了 CTE,在那篇文章中,我了解到:
We can define a CTE as an alternative to a derived table. In a small way, CTE simplifies complex joins and subqueries, improving the readability of the queries.
这里 my attempt 使用 CTE:
WITH temp AS
(
SELECT user_id,
date_time
FROM log_table
WHERE binary event_name = "B" limit 1 )
SELECT *
FROM log_table
WHERE user_id = temp.user_id
AND substring_index(date_time, ' ', 1) = substring_index(temp.date_time, ' ', 1)
ORDER BY date_time
它触发了一个错误:
Query Error: Error: ER_BAD_FIELD_ERROR: Unknown column 'temp.user_id'
in 'where clause'
我被告知唯一的方法是使用 join,然后我尝试如下:
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
我想知道我是否可以意识到使用 CTE,因为 CTE 简化了复杂的连接?
您必须将 CTE 添加到 JOIN。
这将是编写查询的正确方法:
WITH temp AS (
SELECT user_id, date_time
FROM log_table
WHERE binary event_name = "B"
LIMIT 1
)
SELECT l.*
FROM log_table l
JOIN temp ON l.user_id = temp.user_id
AND SUBSTRING_INDEX(l.date_time, ' ', 1) = SUBSTRING_INDEX(temp.date_time, ' ', 1)
ORDER BY l.date_time
->
| user_id | date_time | event_name | trivial |
| ------- | ------------------- | ---------- | ------- |
| 002 | 2020-12-10 10:00:02 | A | 2 |
| 002 | 2020-12-10 10:00:09 | B | 4 |
| 002 | 2020-12-10 10:00:10 | C | 9 |
| 002 | 2020-12-10 10:00:50 | D | 0 |
这是我的 table(创建于 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 |
我从 What is a Common Table Expression? 那里学到了 CTE,在那篇文章中,我了解到:
We can define a CTE as an alternative to a derived table. In a small way, CTE simplifies complex joins and subqueries, improving the readability of the queries.
这里 my attempt 使用 CTE:
WITH temp AS
(
SELECT user_id,
date_time
FROM log_table
WHERE binary event_name = "B" limit 1 )
SELECT *
FROM log_table
WHERE user_id = temp.user_id
AND substring_index(date_time, ' ', 1) = substring_index(temp.date_time, ' ', 1)
ORDER BY date_time
它触发了一个错误:
Query Error: Error: ER_BAD_FIELD_ERROR: Unknown column 'temp.user_id' in 'where clause'
我被告知唯一的方法是使用 join,然后我尝试如下:
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
我想知道我是否可以意识到使用 CTE,因为 CTE 简化了复杂的连接?
您必须将 CTE 添加到 JOIN。
这将是编写查询的正确方法:
WITH temp AS (
SELECT user_id, date_time
FROM log_table
WHERE binary event_name = "B"
LIMIT 1
)
SELECT l.*
FROM log_table l
JOIN temp ON l.user_id = temp.user_id
AND SUBSTRING_INDEX(l.date_time, ' ', 1) = SUBSTRING_INDEX(temp.date_time, ' ', 1)
ORDER BY l.date_time
->
| user_id | date_time | event_name | trivial |
| ------- | ------------------- | ---------- | ------- |
| 002 | 2020-12-10 10:00:02 | A | 2 |
| 002 | 2020-12-10 10:00:09 | B | 4 |
| 002 | 2020-12-10 10:00:10 | C | 9 |
| 002 | 2020-12-10 10:00:50 | D | 0 |