如何在MySQL 5.5中通过联表查询从两张表获取数据
嗨,我来帮你搞定这两张MySQL表的联表查询问题~先理清楚咱们的表结构逻辑:events_dictionary是个枚举字典表,存着所有事件相关的可读名称(比如Light、Switch、on这些),而events_log是日志表,用ID的形式引用字典表里的内容,所以联表查询的核心就是把日志里的ID映射成字典表对应的名称。
先补充下你没写完的events_log建表语句(假设是带参数ID和时间的常见结构,方便后续示例):
DROP TABLE IF EXISTS `events_log`; CREATE TABLE `events_log` ( `log_id` bigint(20) NOT NULL AUTO_INCREMENT, `event_name_id` int(11) NOT NULL DEFAULT '0', `event_param_id` int(11) NOT NULL DEFAULT '0', `create_time` datetime NOT NULL, PRIMARY KEY (`log_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
下面给你几种常用的联表查询场景:
1. 基础内连接:获取日志对应的事件名称
如果只需要把日志里的event_name_id转换成可读名称,用INNER JOIN就够了,它只会返回两边表都有匹配的记录:
SELECT el.log_id, ed.name AS event_name, el.create_time FROM events_log el INNER JOIN events_dictionary ed ON el.event_name_id = ed.id;
这里给表起了别名el(events_log)和ed(events_dictionary),写起来更简洁。ON后面是核心关联条件,把日志的事件ID和字典表的ID对应起来,最后把字典表的name取别名为event_name,结果里就会显示Light、Switch这种可读名称,而不是枯燥的数字ID。
2. 关联两次字典表:同时拿到事件名称和参数
如果你的日志表里还有event_param_id(比如记录开关的on/off状态),这些参数也存在字典表里,那可以关联两次字典表,分别获取对应的名称:
SELECT el.log_id, ed_name.name AS event_name, ed_param.name AS event_param, el.create_time FROM events_log el INNER JOIN events_dictionary ed_name ON el.event_name_id = ed_name.id INNER JOIN events_dictionary ed_param ON el.event_param_id = ed_param.id;
这里给两次关联的字典表起了不同的别名ed_name和ed_param,分别对应事件名称和状态参数,这样查询结果就能直接看到比如Switch + on这种完整的事件描述了。
3. 左连接:保留所有日志记录(兼容脏数据)
如果日志里存在一些event_name_id在字典表里找不到的情况(比如脏数据),但你不想丢失这些日志记录,就用LEFT JOIN,无匹配的字段会显示NULL,还可以用COALESCE把NULL换成友好提示:
SELECT el.log_id, COALESCE(ed.name, '未知事件') AS event_name, el.create_time FROM events_log el LEFT JOIN events_dictionary ed ON el.event_name_id = ed.id;
LEFT JOIN会返回左表(events_log)的所有记录,右表(字典表)没有匹配的话,对应的name字段就是NULL,COALESCE函数可以把NULL替换成“未知事件”,让结果更友好。
内容的提问来源于stack exchange,提问作者NewJ

