You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL多表Join查询:如何筛选供应多个品牌的供应商记录

解决方案

你写的基础三表内连接逻辑是对的,直接在原语句上加GROUP BY+HAVING拿不到正确结果,核心原因是分组会把同供应商的多条品牌明细折叠成单行,既不符合SQL语法规范(非分组字段不能直接写在SELECT子句里),也返回不了你要的所有对应品牌明细。下面两种写法都能实现需求:

写法1:子查询预筛选(兼容性最好,新手友好)

先从关联中间表找出所有供货品牌数大于1的供应商ID,再用这个ID集合过滤原明细查询的结果,所有支持SQL的数据库都能跑:

SELECT s.supplier_name, b.brand_name
FROM Brand b
INNER JOIN Supplier_Brand sb 
  ON b.brand_id = sb.brand_id
INNER JOIN Supplier s 
  ON s.supplier_id = sb.supplier_id
WHERE s.supplier_id IN (
  SELECT supplier_id
  FROM Supplier_Brand
  GROUP BY supplier_id
  HAVING COUNT(DISTINCT brand_id) > 1
);

小提示:COUNT里加DISTINCT是为了兼容中间表可能存在的重复关联脏数据,如果你的Supplier_Brand表已经给supplier_id和brand_id建了联合唯一约束,直接写COUNT(brand_id)就行,结果完全一致。

写法2:窗口函数实现(适合支持现代SQL的环境)

如果你的数据库是MySQL 8.0及以上、PostgreSQL、SQL Server等支持窗口函数的版本,可以不用子查询,直接在关联时计算每个供应商的合作品牌总数再过滤:

SELECT supplier_name, brand_name
FROM (
  SELECT
    s.supplier_name,
    b.brand_name,
    COUNT(DISTINCT b.brand_id) OVER (PARTITION BY s.supplier_id) AS total_brand
  FROM Brand b
  INNER JOIN Supplier_Brand sb
    ON b.brand_id = sb.brand_id
  INNER JOIN Supplier s
    ON s.supplier_id = sb.supplier_id
) tmp
WHERE total_brand > 1;

新手容易踩的坑

  • 别直接在原查询末尾硬加GROUP BY s.supplier_id HAVING COUNT(...) >1:标准SQL要求SELECT子句里只能出现分组字段和聚合函数,强行写非分组的brand_name要么直接报错,要么在开启非严格模式的旧版MySQL里返回随机的品牌值,结果完全不可靠。
  • 计数时记得对品牌ID去重,避免中间表重复录入同一条关联关系导致计数虚高。

内容的提问来源于stack exchange,提问作者frankBang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:01:19