首页 文章

将SQL查询转换为查询构建器样式

提问于
浏览
6

我试着了解如何将一个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转换为查询构建器 . 我希望当我看到一个良好的工作转换我的查询时,我可以理解下次我该怎么做 .

2 回答

  • 0

    以下Query Builder代码将为您提供 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环境中尝试它们,以确保它们以indended的形式工作 . 然后我使用查询生成器逐步实现它们,但是在查询结束时不使用 get() ,而是使用 toSql() ,这将为查询生成器生成的查询提供字符串表示,允许我进行比较这是我原来的查询,以确保它是相同的 .

  • 1

    这项工作对我来说:

    DB :: table('wouter_blog_posts') - > whereNotNull('published') - > where('published',1) - > whereNotNull('published_at') - > whereRaw('published_at <NOW()') - > whereRaw(“(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 . ”'))> = 1“) - > orderBy('published_at','desc') - > skip(0) - > take(10) - > paginate($ this-> property('postsPerPage'));

相关问题