简体   繁体   English

Laravel - 查询以多对多关系连接表

[英]Laravel - query to join tables in Many to many relation

I have the below tables我有下表

posts
    - id
    - name

categories
    - id
    - name

category_post
    - post_id
    - category_id

Post.php后.php

public function Category()
{
    return $this->belongsToMany(Category::class);
}

Category.php分类.php

public function posts()
{
    return $this->belongsToMany(Post::class);
}

A post may contain many categories.一个帖子可能包含许多类别。

I want to query all posts related to the categories of any given post in the least number of database queries.我想在最少的数据库查询中查询与任何给定帖子的类别相关的所有帖子

For example, If a post belongs to three categories, I want to get all the posts related to that three categories.例如,如果一个帖子属于三个类别,我想获取与这三个类别相关的所有帖子。 I could achieve this in 4 DB queries as below.我可以在 4 个数据库查询中实现这一点,如下所示。

$post = Post::find(1);

$categoryIds = $post->category()->pluck('id');

$postIds = DB::table('category_post')
    ->whereIn('category_id', $categoryIds)
    ->pluck('post_id')
    ->unique();

$relatedPosts = DB::table('posts')
    ->whereIn('id', $postIds)
    ->get();

Any help would be highly appreciated to reduce DB queries or refactor the code in laravel way.任何有助于减少数据库查询或以 laravel 方式重构代码的帮助将不胜感激。 Thanks谢谢

Your given example can be written like:你给定的例子可以写成:

$postWithRelatedPosts = Post::whereHas('category.post', function ($q) {
    $q->where('id', 1);
})->get();

This is a single query but has 2 sub-queries within it.这是一个单一的查询,但其中有 2 个子查询。 It generates something like:它会产生类似的东西:

select * 
from `posts` 
where exists (
    select * 
    from `categories` inner join `category_post` on `categories`.`id` = `category_post`.`category_id` 
    where `posts`.`id` = `category_post`.`post_id` and exists (
         select * 
         from `posts` inner join `category_post` on `posts`.`id` = `category_post`.`post_id` 
         where `categories`.`id` = `category_post`.`category_id` and `id` = ?
    )

)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM