使用变量与Inner Join的MySQL查询未返回正确结果
问题:MariaDB关联查询返回ID与预期不符
我是MySQL新手,需为MariaDB数据库编写查询语句。现有user表和Contacts表,Contacts表包含两个外键,user表包含email和user id。我想要获取指定用户ID(示例为25)的所有联系人的id和email,由于目标用户ID可能出现在联系人关系的first_id或second_id字段中,因此使用了变量。执行以下查询:
SELECT id, email, @use := IF(first_id = 25, second_id, first_id) FROM contacts INNER JOIN user ON @use = user.id WHERE first_id = 25 OR second_id = 25;
返回结果如下:
+----+-------------------------+-------------------------------------------+ | id | email | @use:= IF(first_id=25,second_id,first_id) | +----+-------------------------+-------------------------------------------+ | 23 | secretemail@gmail.com | 23 | | 23 | best.secretem@yahoo.com | 24 | | 24 | wow.spa@web.de | 23 | +----+-------------------------+-------------------------------------------+
令我困惑的是,使用Inner Join时返回的id与预期不匹配,恳请帮忙解答。
问题原因及解决方案
你用变量做关联的方式存在逻辑漏洞——MySQL/MariaDB中,变量赋值和JOIN的执行顺序没有明确的先后保证,ON子句里的@use可能还没被SELECT中的赋值语句更新,导致关联逻辑混乱,最终出现ID和邮箱不匹配的情况。
推荐两种更可靠的写法:
方案一:用CASE表达式明确关联逻辑
SELECT u.id, u.email FROM contacts c JOIN user u ON u.id = CASE WHEN c.first_id = 25 THEN c.second_id ELSE c.first_id END WHERE c.first_id = 25 OR c.second_id = 25;
方案二:用UNION拆分两种关联场景(更直观)
SELECT u.id, u.email FROM contacts c JOIN user u ON c.second_id = u.id WHERE c.first_id = 25 UNION SELECT u.id, u.email FROM contacts c JOIN user u ON c.first_id = u.id WHERE c.second_id = 25;
这两种写法都能避免变量带来的执行顺序问题,逻辑清晰且结果准确。其中UNION还会自动去除重复的联系人记录(如果存在的话)。
内容的提问来源于stack exchange,提问作者THE YAAAAA
相关产品推荐
相关产品推荐

