需要帮助将嵌套连接查询转换为Laravel Eloquent

时间:2015-12-27 16:10:08

标签: mysql laravel laravel-5 eloquent laravel-5.1

需要一些帮助才能在Laravel中进行查询。

我在laravel之外尝试了这个查询并且它可以工作:

SELECT t.*
FROM
        stories AS t
    JOIN
        ( SELECT created_at
          FROM stories
          WHERE id = 126
        ) AS o
      ON t.created_at = o.created_at AND t.id > 126
      OR t.created_at < o.created_at
ORDER BY
    t.created_at DESC LIMIT 30;

说明:基本上它需要分页,因为当用户转到下一页时,它会向他们显示在指定ID之前创建的30个故事。当我通过created_at对故事进行排序时,它们会变成随机的,所以我需要在我使用上述查询完成的特定行之后获得接下来的30行。 126是上一页上最​​后一个故事的id,它将是实际代码中的一个变量。

因此,当我尝试在Laravel Eloquent中使用它时,无论我做什么,我都无法使其发挥作用。

我试过

$result = App\Story::join(DB::table('stories AS last_story')->find($previous_last_post_id), function($join)
        {
            $join->on('stories.created_at', '=', 'last_story.created_at')
            ->where('stories.id', '>', 'last_story.id')
            ->orWhere('stories.created_at', '<', 'last_story.created_at');
        })
        ->get()

哪个给了我

  

Grammar.php中的ErrorException第39行:类stdClass的对象无法转换为字符串

将子查询更改为

DB::table('stories AS last_story')->where('id', $previous_last_post_id)->get()

给了我:

  

Grammar.php第39行中的ErrorException:数组转换为字符串

放弃并尝试原始查询:

$result = DB::select("SELECT t.*
FROM
        stories AS t
    JOIN
        ( SELECT created_at
          FROM stories
          WHERE id = 126
        ) AS o
      ON t.created_at = o.created_at AND t.id > 126
      OR t.created_at < o.created_at
ORDER BY
    t.created_at DESC LIMIT 30")

但那给了我

  

e969125ed5dcf92ec33b84157c0eb37a第88行中的FatalErrorException:在字符串

上调用成员函数toFormattedDateString()

3 个答案:

答案 0 :(得分:0)

而不是返回数组的get(),请尝试使用first()

答案 1 :(得分:0)

为什么不使用laravel内置的分页?

$stories = App\Story::orderBy('created_at')->simplePaginate(30);

它将使用URL参数跟踪当前页码。

您可以使用以下方式打印上一个/下一个按钮:

{!! $stories->render() !!}

https://laravel.com/docs/5.1/pagination

答案 2 :(得分:0)

好的,所以我开展工作的唯一方法是:

DB::select('
    SELECT t.id
    FROM
        stories AS t
    JOIN
        (
            SELECT created_at
            FROM stories
            WHERE id = ?
        ) AS o
    ON t.created_at = o.created_at AND t.id > ?
        OR t.created_at < o.created_at
    ORDER BY t.created_at DESC LIMIT 30
', [$previous_last_post_id, $previous_last_post_id]);

我创建了一个几乎完全相同的雄辩查询:

DB::table('stories')
    ->select('stories.id')
    ->join(DB::raw("(SELECT id, created_at FROM stories WHERE id = 126) as last_story"), function($join)
    {
        $join->on('stories.created_at', '=', 'last_story.created_at')
        ->where('stories.id', '>', 'last_story.id')
        ->orWhere('stories.created_at', '<', 'last_story.created_at');
    })->orderBy('stories.created_at', 'DESC')->take(30)->get();

但它返回了错误的结果,所以我想这里不可能避免使用原始SQL。