Laravel多对多关联中如何统计各标签对应的未绑定该标签的文章数量
实现方案
1. 原生SQL通用实现
核心逻辑:全局总文章数减去当前标签已关联的文章数,就是未使用该标签的文章总数。
先预设三个表的基础字段结构:
- posts表:主键
id,存储所有文章数据 - tags表:主键
id,标签名称字段name - posts_tags中间表:外键
post_id关联posts.id,外键tag_id关联tags.id
查询语句如下:
SELECT t.name AS tag_name, (SELECT COUNT(*) FROM posts) - COUNT(DISTINCT pt.post_id) AS unused_post_count FROM tags t LEFT JOIN posts_tags pt ON t.id = pt.tag_id GROUP BY t.id, t.name;
如果需要直接输出示例中的拼接格式,可以调整SQL:
SELECT CONCAT(t.name, '(', (SELECT COUNT(*) FROM posts) - COUNT(DISTINCT pt.post_id), '篇文章未使用该标签)') AS tag_show_text FROM tags t LEFT JOIN posts_tags pt ON t.id = pt.tag_id GROUP BY t.id, t.name;
注意:如果需要排除草稿、软删除等无效文章,要给统计总文章数的子查询加对应WHERE条件,关联查询部分也要同步加过滤条件避免统计错误。
2. 常见ORM实现示例
Laravel Eloquent
先在Tag模型中定义多对多关联:
// app/Models/Tag.php public function posts() { return $this->belongsToMany(Post::class, 'posts_tags'); }
查询代码:
$totalPosts = Post::count(); $tags = Tag::withCount('posts')->get()->map(function($tag) use ($totalPosts) { $unusedCount = $totalPosts - $tag->posts_count; return "{$tag->name}({$unusedCount}篇文章未使用该标签)"; });
Django ORM
定义好模型关联后直接查询:
from django.db.models import Count from .models import Tag, Post total_posts = Post.objects.count() tags = Tag.objects.annotate(used_post_count=Count('posts')).all() tag_show_list = [f"{tag.name}({total_posts - tag.used_post_count}篇文章未使用该标签)" for tag in tags]
内容的提问来源于stack exchange,提问作者Harrika
相关产品推荐
相关产品推荐

