orest's avatar
Level 13

query using recursive CTE

I have the following tables

Category

- id
- parent_id
- title

Threads

- id
- category_id
- title

A category have sub-categories and only the "leaf" category can have threads To explain further with an example

Computer -> Mac -> macbook

In this case the category macbook can have threads while the parent categories can't have threads.

What i want to achieve is to find the latest thread of a category, among all sub-categories

Computer -> Mac -> macbook
Computer -> Windows-> HP

In the example above, the categories macbook and HP have threads and i want for the parent category Computer to find the latest thread among the categories macbook and HP

To achieve that i am using recursive CTE and it seems to work when i test it with sqlite but when i use mysql it doesn't work

public function scopeWithLatestThread($query)
{
	return $query->addSelect(DB::raw('(
            SELECT
                id
            FROM
                threads
            WHERE
                threads.category_id in
                    (
                        with recursive recursive_categories (id) as
                        (
                            SELECT id
                            from categories as initial_categories
                            where initial_categories.id=categories.id
                            UNION ALL
                            SELECT remaining_categories.id
                            FROM recursive_categories JOIN categories as remaining_categories
                            on recursive_categories.id=remaining_categories.parent_id
                        )
                        SELECT id FROM recursive_categories
                    )
            ORDER BY
                updated_at DESC
            LIMIT 1) AS latest_thread_id')
        )->with('latestThread');     
}
public function latestThread()
{
    return $this->belongsTo(Thread::class);
}

Category::whereNull('parent_id')->withLatestThread()->get();
0 likes
2 replies
PaulMaxOS's avatar

Hi @orest , what version of MySQL are you using? I believe the with syntax is something that you'd use in MySQL 8 only.

orest's avatar
Level 13

i am using MySQL 8.

I ended up using sql functions because for some reason the categories.id was not synchronised and its value was always the same when i used the query above

Please or to participate in this conversation.