如何在保持行唯一性的前提下执行INNER JOIN查询
解决三元表关联后的唯一Offer统计问题
我明白你现在的困扰:直接关联ternary和Offer表时,因为一个Offer在三元表里会对应多条Profile/Skill记录,导致统计结果变成了匹配次数,而不是你想要的唯一Offer数量。下面一步步给你解决思路和正确的查询语句:
首先修正你原查询的语法错误
你之前的查询把GROUP BY放在了WHERE前面,这是SQL语法错误,正确顺序是WHERE在前,GROUP BY在后。不过这只是语法问题,核心问题还是重复计数的问题。
核心解决方案:先去重三元表中的Offer记录
因为ternary里同一个id_Offer会有多条记录(对应不同的Profile/Skill),所以我们需要先从ternary中提取出唯一的id_Offer,再和Offer表关联统计。
场景1:统计business-1在三元表中存在的唯一Offer数量
SELECT o.business_name, COUNT(DISTINCT t.id_Offer) AS unique_offer_count FROM Offer o INNER JOIN ( -- 先从三元表中取出唯一的id_Offer SELECT DISTINCT id_Offer FROM ternary ) t ON o.id_Offer = t.id_Offer WHERE o.business_name = 'business-1' GROUP BY o.business_name;
这个查询会返回business-1对应的唯一Offer数量(也就是你说的2条),而不是匹配的行数。
场景2:按id_Skill筛选,返回对应的business_name及唯一Offer数
比如要筛选出包含id_Skill=1的Offer所属的商家,以及每个商家的唯一Offer数量:
SELECT o.business_name, COUNT(DISTINCT t.id_Offer) AS unique_offer_count FROM Offer o INNER JOIN ( SELECT DISTINCT id_Offer FROM ternary WHERE id_Skill = 1 -- 这里添加skill筛选条件 ) t ON o.id_Offer = t.id_Offer GROUP BY o.business_name ORDER BY unique_offer_count DESC;
场景3:按id_Profile筛选,返回对应的business_name
如果你只需要返回符合条件的商家名称,不需要计数,可以这样写:
SELECT DISTINCT o.business_name FROM Offer o INNER JOIN ternary t ON o.id_Offer = t.id_Offer WHERE t.id_Profile = 1 -- 替换成你要筛选的Profile ID GROUP BY o.business_name;
或者更简洁的方式,用EXISTS子查询避免重复:
SELECT DISTINCT o.business_name FROM Offer o WHERE EXISTS ( SELECT 1 FROM ternary t WHERE t.id_Offer = o.id_Offer AND t.id_Profile = 1 -- 筛选条件 );
关于你提到的解决方案中的?
那个?是SQL参数占位符(通常在Java JDBC这类开发框架中使用),不是MariaDB的原生语法,你需要把它替换成实际的筛选值(比如id_Skill = 2或者id_Profile = 5),这样就能正常运行了。
内容的提问来源于stack exchange,提问作者monkey intern
相关产品推荐
相关产品推荐

