mysql - 如何在 SQL 中 JOIN 后获取最后 N 条记录?
问题描述
我在 mysql 中有三个表 -
表 1:注释
+---------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| user_id | int | NO | MUL | NULL | |
| note_id | varchar(25) | NO | UNI | NULL | |
| topic | text | NO | | NULL | |
| note_html | text | NO | | NULL | |
| note_markdown | text | NO | | NULL | |
| access_type | varchar(25) | NO | | NULL | |
| date | date | NO | | NULL | |
| time | time | NO | | NULL | |
+---------------+-------------+------+-----+---------+----------------+
表 2:notes_subject
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| user_id | int | NO | | NULL | |
| note_id | varchar(25) | NO | MUL | NULL | |
| subject_name | text | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
表 3:notes_tag
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| user_id | int | NO | | NULL | |
| note_id | varchar(25) | NO | MUL | NULL | |
| tag_name | text | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
并假设存储在notes表中的内容为(我将保留此表的一些属性,例如note_html,note_markdown,因为它具有大量数据)-
+----+---------+--------------+------------+----------+
| id | user_id | note_id | date | time |
+----+---------+--------------+------------+----------+
| 1 | 2 | nVf0It70bnjQ | 2020-08-08 | 11:18:17 |
| 3 | 2 | RfYg3u59Ytup | 2020-08-06 | 12:50:51 |
| 6 | 1 | e657ZxsYaWR2 | 2020-08-06 | 10:43:08 |
| 7 | 2 | ARJuTcItPgbn | 2020-08-10 | 11:19:11 |
| 8 | 2 | BW2aMLYN8CIF | 2020-08-10 | 11:24:35 |
+----+---------+--------------+------------+----------+
并假设存储在notes_subject表中的内容为 -
+----+---------+--------------+--------------+
| id | user_id | note_id | subject_name |
+----+---------+--------------+--------------+
| 1 | 2 | nVf0It70bnjQ | computer |
| 3 | 2 | RfYg3u59Ytup | SQL |
| 6 | 1 | e657ZxsYaWR2 | computer |
| 7 | 2 | ARJuTcItPgbn | CN |
| 8 | 2 | BW2aMLYN8CIF | DLD |
+----+---------+--------------+--------------+
并假设存储在notes_tag表中的内容为 -
+-----+---------+--------------+--------------+
| id | user_id | note_id | tag_name |
+-----+---------+--------------+--------------+
| 7 | 1 | e657ZxsYaWR2 | definition |
| 70 | 2 | nVf0It70bnjQ | computer fan |
| 71 | 2 | nVf0It70bnjQ | clean |
| 250 | 2 | RfYg3u59Ytup | sql |
| 251 | 2 | RfYg3u59Ytup | mysql |
| 252 | 2 | RfYg3u59Ytup | select |
| 253 | 2 | RfYg3u59Ytup | ASC |
| 254 | 2 | RfYg3u59Ytup | DESC |
| 257 | 2 | ARJuTcItPgbn | cn |
| 258 | 2 | ARJuTcItPgbn | IPV4 |
| 261 | 2 | BW2aMLYN8CIF | AND |
| 262 | 2 | BW2aMLYN8CIF | NAND |
+-----+---------+--------------+--------------+
我用JOIN
这三个表 -
SELECT N.id, N.user_id, N.note_id, S.subject_name, T.tag_name, N.date, N.time
from notes AS N
JOIN notes_subject AS S ON N.user_id = 2
AND N.user_id = S.user_id
AND N.note_id = S.note_id
JOIN notes_tag AS T ON N.user_id = T.user_id
AND N.note_id = T.note_id
ORDER BY N.date DESC
LIMIT 3
它获取了 -
结果 1:
+----+---------+--------------+--------------+----------+------------+----------+
| id | user_id | note_id | subject_name | tag_name | date | time |
+----+---------+--------------+--------------+----------+------------+----------+
| 7 | 2 | ARJuTcItPgbn | CN | cn | 2020-08-10 | 11:19:11 |
| 7 | 2 | ARJuTcItPgbn | CN | IPV4 | 2020-08-10 | 11:19:11 |
| 8 | 2 | BW2aMLYN8CIF | DLD | AND | 2020-08-10 | 11:24:35 |
+----+---------+--------------+--------------+----------+------------+----------+
如果我在没有 的情况下运行上面的查询LIMIT
,它会获取 -
结果 2:
+----+---------+--------------+--------------+--------------+------------+----------+
| id | user_id | note_id | subject_name | tag_name | date | time |
+----+---------+--------------+--------------+--------------+------------+----------+
| 7 | 2 | ARJuTcItPgbn | CN | cn | 2020-08-10 | 11:19:11 |
| 7 | 2 | ARJuTcItPgbn | CN | IPV4 | 2020-08-10 | 11:19:11 |
| 8 | 2 | BW2aMLYN8CIF | DLD | AND | 2020-08-10 | 11:24:35 |
| 8 | 2 | BW2aMLYN8CIF | DLD | NAND | 2020-08-10 | 11:24:35 |
| 1 | 2 | nVf0It70bnjQ | computer | computer fan | 2020-08-08 | 11:18:17 |
| 1 | 2 | nVf0It70bnjQ | computer | clean | 2020-08-08 | 11:18:17 |
| 3 | 2 | RfYg3u59Ytup | SQL | sql | 2020-08-06 | 12:50:51 |
| 3 | 2 | RfYg3u59Ytup | SQL | mysql | 2020-08-06 | 12:50:51 |
| 3 | 2 | RfYg3u59Ytup | SQL | select | 2020-08-06 | 12:50:51 |
| 3 | 2 | RfYg3u59Ytup | SQL | ASC | 2020-08-06 | 12:50:51 |
| 3 | 2 | RfYg3u59Ytup | SQL | DESC | 2020-08-06 | 12:50:51 |
+----+---------+--------------+--------------+--------------+------------+----------+
在结果 1中:最后插入了三行 ID (7,7,8)。但结果必须像 -
+----+---------+--------------+--------------+--------------+------------+----------+
| id | user_id | note_id | subject_name | tag_name | date | time |
+----+---------+--------------+--------------+--------------+------------+----------+
| 7 | 2 | ARJuTcItPgbn | CN | cn | 2020-08-10 | 11:19:11 |
| 7 | 2 | ARJuTcItPgbn | CN | IPV4 | 2020-08-10 | 11:19:11 |
| 8 | 2 | BW2aMLYN8CIF | DLD | AND | 2020-08-10 | 11:24:35 |
| 8 | 2 | BW2aMLYN8CIF | DLD | NAND | 2020-08-10 | 11:24:35 |
| 1 | 2 | nVf0It70bnjQ | computer | computer fan | 2020-08-08 | 11:18:17 |
| 1 | 2 | nVf0It70bnjQ | computer | clean | 2020-08-08 | 11:18:17 |
+----+---------+--------------+--------------+--------------+------------+----------+
结果必须包含在特定 ID 的所有 tag_name 中。
解决方案
将限制放在子查询中,该子查询在加入前获取 3 个最新注释。
SELECT N.id, N.user_id, N.note_id, S.subject_name, T.tag_name, N.date, N.time
from (SELECT *
FROM notes
WHERE user_id = 2
ORDER BY date DESC
LIMIT 3) AS N
JOIN notes_subject AS S ON N.user_id = S.user_id
AND N.note_id = S.note_id
JOIN notes_tag AS T ON N.user_id = T.user_id
AND N.note_id = T.note_id
推荐阅读
- google-calendar-api - Google 服务帐户:委托域范围的授权以仅模拟一个用户
- java - 如何停止上一个正在收听 kafka-topic 的线程
- angular - Http GET,角度
- go - 安装base64的问题
- html - jQuery将JSON项目值写入每个带有id的td
- activemq-artemis - ActiveMQ Artemis - 集群代理
- python - 随机读取 50% 的文件
- php - NGINX/PHP 无法访问根目录外的文件
- amazon-web-services - 如何自动将数据导入 AWS RDS
- firebase-cloud-messaging - Firebase 消息 - 订阅的最大频率