简体   繁体   中英

Get categories order by their posts in laravel

I want to get top 5 categories by the number of their posts, example:

Cat 1 = 10 posts
Cat 2 = 7 posts
Cat 3 = 5 posts
Cat 4 = 3 posts
Cat 5 = 2 posts

I know I can get my categories with their posts by eager load and count the posts number of each category but that doesn't give me asc order in categories so i was thinking of join query.

here is what I've made so far and has this issues

  1. I cannot put status of posts (just get postes with published status and count them only)
  2. I get this error

    SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'publish' in where clause is ambiguous (SQL: select * from categories inner join posts on posts . categories = categories . id where publish = 1 limit 5)

code

$categoriesbyposts = Category::where('publish', '=', 1)
  ->join('posts', 'posts.categories', '=', 'categories.id')
  // ->where('posts.publish', '=', 1)
  ->take(5)
  ->get(); 

PS: I might need to mention there is no category_id column in my posts table i am using 3rd table for that matter named post_categories and it gets post_id and category_id .

Any idea?

Update

post model

public function categories(){
        return $this->belongsToMany(Category::class, 'post_categories', 'post_id', 'category_id');
    }

category model

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

Update 2

I ended up with code below and it returns me 5 posts instead of 5 categories!

$categoriesbyposts = DB::table('categories')
            ->where('categories.publish', '=', 1)
            ->join('post_categories', 'post_categories.category_id', '=', 'categories.id')
            ->join('posts', 'posts.id', '=', 'post_categories.post_id')
            ->groupby('categories.id')
            ->take(5)
            ->get();

Try this and let me know what the results are

$results = DB::select('
    SELECT c.category_name, c.slug, COUNT(pc.post_id) AS `post_count`
    FROM categories AS c JOIN post_categories AS pc
    ON c.id = pc.category_id
    JOIN posts AS p
    ON posts.id = post_categories.post_id
    WHERE c.publish = 1 AND p.publish = 1
    GROUP BY category_name
    ORDER BY post_count DESC
    LIMIT 5
');

Another alternative would be

$results = Category::selectRaw('categories.category_name, categories.slug,  COUNT(post_categories.post_id) AS `post_count`')
            ->join('post_categories', 'categories.id', '=', 'post_categories.category_id')
            ->join('posts', 'posts.id', '=', 'post_categories.post_id')
            ->whereRaw('categories.publish = 1 AND posts.publish = 1')
            ->groupBy('category_name')
            ->orderBy('post_count', 'DESC')
            ->limit(5)
            ->get();

please add table name in where condition which table apply this condition

select * from categories inner join posts on posts.categories=categories.id where categories.publish= 1 limit 5)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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