Laravel通过另一个表的列获取项目

时间:2014-08-29 08:48:06

标签: php laravel orm eloquent

所以,我几天前开始学习laravel,现在我对雄辩的ORM有疑问。

我有两张桌子:

Links:
╔════╦═══════╗
║ Id ║ Name  ║
╠════╬═══════╣
║ 1  ║ test  ║
║ 2  ║ test2 ║
╚════╩═══════╝

Likes:
╔════╦═════════╦═══════╦══════════════════╗
║ Id ║ link_id ║ total ║ created_at       ║
╠════╬═════════╬═══════╬══════════════════╣
║ 1  ║ 1       ║ 5     ║ 2014.08.27 11:32 ║
║ 2  ║ 2       ║ 10    ║ 2014.08.29 07:07 ║
╚════╩═════════╩═══════╩══════════════════╝

每天我在likes表格中创建新行,然后为每个新的列增加列total。我这样做的原因,因为我需要根据今天,本周和本月每个链接有多少喜欢来过滤。所以,我不知道如何在Eloquent ORM中做到这一点。由于有急切加载看起来不可能,因为有2个不同的查询,我需要类似于JOINS的东西才能在1个查询中使用这两个表。

我当前的查询:

$links = Link::with('likes')->paginate(10);

任何想法,我怎么做?

抱歉我的英文。感谢。

修改

SQL中的查询应类似于:

  

SELECT * FROM links AS ln LEFT JOIN喜欢AS lk ON ln.id =   lk.link_id WHERE lk.created_at BETWEEN'2014-08-28 09:52:58'和   '2014-08-29 09:52:58'LEDER BY lk.total

2 个答案:

答案 0 :(得分:1)

我不确定这是否有用,但这是一次尝试;

好几天

$days = Link::leftJoin('likes', 'likes.id', '=', 'links.id')
->whereBetween('likes.created_at', array(Carbon::now()->subDay(), Carbon::now()))
->orderBy(likes.total)->get();

几个月

$months = Link::leftJoin('likes', 'likes.id', '=', 'links.id')
->whereBetween('likes.created_at', array(Carbon::now()->subMonth(), Carbon::now()))
->orderBy('likes.total')->get();

几周

$months = Link::leftJoin('likes', 'likes.id', '=', 'links.id')
->whereBetween('likes.created_at', array(Carbon::now()->subWeek(), Carbon::now()))
->orderBy('likes.total')->get();

问题在于,链接中的id列将被like id列中的值覆盖。要解决此问题,请在select()或get()中选择要使用的数据。

答案 1 :(得分:0)

好的,我找到了使用groupBy的解决方案,当然现在我不能使用 - > paginate,但我可以手动制作,所以它不是一个大问题。

我有点改变likes表,现在我使用COUNT而不是SUM,但它应该同时适用于这两种情况。

return self::select('links.*')
            ->addSelect(DB::raw("COUNT(`likes`.`id`) AS `total_likes`"))
            ->join('likes', 'likes.link_id', '=', 'links.id')
            ->whereBetween('likes.created_at', array($start, $end))
            ->groupBy('likes.link_id')
            ->orderBy('total_likes', 'DESC')
            ->take($limit);

还有另一种方法可以使用 - > paginate,但我认为使用它并不好:

$links = Link::select('*')
                ->addSelect(DB::raw("(SELECT COUNT(`likes`.`id`) FROM `likes` WHERE `likes`.`link_id` = `links`.`id` AND `likes`.`created_at` BETWEEN '$start' AND '$end')  AS `total_likes`"))
                ->orderBy('total_likes', 'DESC')
                ->whereHas('likes', function($query) use ($start, $end) {
                    $query->whereBetween('created_at', array($start, $end));
                })->paginate(15);