将SQL查询转换为查询生成器样式


convert SQL query to query builder style

我几天来一直在努力了解如何将SQL查询转换为laravel中的查询生成器样式。

我的SQL查询是:

$tagid = Db::select("SELECT `id` FROM `wouter_blog_tags` WHERE `slug` = '".$this->param('slug')."'");
$blog = Db::select("SELECT * 
            FROM `wouter_blog_posts` 
            WHERE `published` IS NOT NULL 
            AND `published` = '1'
            AND `published_at` IS NOT NULL 
            AND `published_at` < NOW()
            AND (
            SELECT count( * ) 
            FROM `wouter_blog_tags` 
            INNER JOIN `wouter_blog_posts_tags` ON `wouter_blog_tags`.`id` = `wouter_blog_posts_tags`.`tags_id` 
            WHERE `wouter_blog_posts_tags`.`post_id` = `wouter_blog_posts`.`id` 
            AND `id` 
            IN (
             '".$tagid[0]->id."'
            )) >=1
            ORDER BY `published_at` DESC 
            LIMIT 10 
            OFFSET 0");

我现在要转换到查询生成器的地方是:

   $test = Db::table('wouter_blog_posts')
->where('published', '=', 1)
->where('published', '=', 'IS NOT NULL')
->where('published_at', '=', 'IS NOT NULL')
->where('published_at', '<', 'NOW()')
  ->select(Db::raw('count(*) wouter_blog_tags'))
->join('wouter_blog_posts_tags', function($join)
{ 
$join->on('wouter_blog_tags.id', '=', 'wouter_blog_posts_tags.tags_id')
->on('wouter_blog_posts_tags.post_id', '=', 'wouter_blog_posts.id')
->whereIn('id', $tagid[0]->id);
})
->get();

我读到我不能在联接中使用whereIn。我现在得到的错误:

调用未定义的方法Illuminate''Database''Query''JoinClause::whereIn((

我真的不知道如何将SQL转换为查询生成器。我希望当我看到一个很好的查询转换时,我能理解下次该怎么做。

这对我来说很有效:

DB::表('outer_blog_posts'(->where NotNull(已发布(->其中("已发布",1(->where NotNull('published_at'(->where Raw('published_at<NOW(('(->whereRaw("(SELECT计数(*(来自wouter_blog_tags内部连接wouter_blog_posts_tagswouter_blog_tagsidwouter_blog_posts_tagstags_id其中wouter_blog_posts_tagspost_idwouter_blog_postsidid在('".$tagid。"'))>=1"(->orderBy('published_at','desc'(->跳过(0(->take(10(->paginate($this->属性('postsPerPage'((;

以下查询生成器代码将为您提供DB::select中的确切SQL查询:

DB::table('wouter_blog_posts')
    ->whereNotNull('published')
    ->where('published', 1)
    ->whereNotNull('published_at')
    ->whereRaw('`published_at` < NOW()')
    ->where(DB::raw('1'), '<=', function ($query) use ($tagid) {
        $query->from('wouter_blog_tags')
            ->select('count(*)')
            ->join('wouter_blog_posts_tags', 'wouter_blog_tags.id', '=', 'wouter_blog_posts_tags.tags_id')
            ->whereRaw('`wouter_blog_posts_tags`.`post_id` = `wouter_blog_posts`.`id`')
            ->whereIn('id', [$tagid[0]->id]);
    })
    ->orderBy('published_at', 'desc')
    ->skip(0)
    ->take(10)
    ->get();

必须反转子查询条件,因为不能将子查询作为where方法的第一个参数,并且仍然能够绑定条件值。所以它是1 <= (subquery),相当于(subquery) >= 1。以上代码生成的查询将如下所示:

SELECT * 
FROM `wouter_blog_posts` 
WHERE `published` IS NOT NULL 
       AND `published` = 1 
       AND `published_at` IS NOT NULL 
       AND `published_at` < Now() 
       AND 1 <= (SELECT `count(*)` 
                 FROM `wouter_blog_tags` 
                      INNER JOIN `wouter_blog_posts_tags` 
                              ON `wouter_blog_tags`.`id` = 
                                 `wouter_blog_posts_tags`.`tags_id` 
                 WHERE `wouter_blog_posts_tags`.`post_id` = 
                       `wouter_blog_posts`.`id` 
                        AND `id` IN ( ? )) 
ORDER  BY `published_at` DESC 
LIMIT  10 offset 0 

当创建更复杂的查询时,我的过程是首先创建它们,并在SQL环境中进行尝试,以确保它们能够独立运行。然后,我使用查询生成器一步一步地实现它们,但我没有在查询结束时使用get(),而是使用toSql(),它将为我提供查询生成器生成的查询的字符串表示,使我能够将其与原始查询进行比较,以确保其相同。