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

如何用LEFT JOIN实现关联表计数>1的SELECT查询?获取多字段关联非空分类

基础问题解答:LEFT JOIN + 关联表计数>1的SELECT查询

假设你有主表categories(分类表)和关联表products(产品表),要查询关联产品数量大于1的分类,基础SQL写法如下:

SELECT c.*, COUNT(p.id) AS product_count
FROM categories c
LEFT JOIN products p ON p.category_id = c.id
GROUP BY c.id
HAVING COUNT(p.id) > 1;
  • 用LEFT JOIN关联两张表,确保所有分类都被纳入查询,COUNT(p.id)统计的是关联的有效产品数(仅统计p.id不为空的记录)
  • GROUP BY c.id按分类分组,保证每个分类只返回一条结果
  • 必须用HAVING筛选聚合后的计数结果,WHERE在分组前执行,无法处理聚合值

实际场景解决方案:Laravel中筛选关联任意分类字段的非空分类

你当前的写法有明显问题:DB::select()返回的是原生查询结果数组,根本没法链式调用Eloquent的withCount()方法,会直接报错。另外你需要匹配产品表的category_root、category_parent、category_id三个字段与分类ID的关联,以下是两种可行方案:

方案1:Eloquent子查询(性能最优)

直接用whereExists判断分类是否存在关联产品(三个字段任意匹配即可):

$categories = Category::whereExists(function ($query) {
    $query->select(DB::raw(1))
          ->from('products')
          ->whereRaw('products.category_root = categories.id 
                      OR products.category_parent = categories.id 
                      OR products.category_id = categories.id');
})->get();

方案2:原生SQL查询(适合复杂场景)

如果更习惯原生SQL,写法如下:

SELECT c.*
FROM categories c
WHERE EXISTS (
    SELECT 1 FROM products p
    WHERE p.category_root = c.id 
       OR p.category_parent = c.id 
       OR p.category_id = c.id
);

对应的Laravel调用:

$categories = DB::select('SELECT c.* FROM categories c WHERE EXISTS (SELECT 1 FROM products p WHERE p.category_root = c.id OR p.category_parent = c.id OR p.category_id = c.id)');

补充:同时统计关联产品数量

如果还要统计每个分类的关联产品总数(三个字段匹配的都算),可以在Category模型里定义自定义关联:

public function relatedProducts()
{
    return $this->hasMany(Product::class)
                ->where(function ($query) {
                    $query->where('category_root', $this->id)
                          ->orWhere('category_parent', $this->id)
                          ->orWhere('category_id', $this->id);
                });
}

然后查询时:

$categories = Category::withCount('relatedProducts')
                      ->where('relatedProducts_count', '>', 0)
                      ->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:37:35