将 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。我现在得到的错误:
Call to undefined method Illuminate\Database\Query\JoinClause::whereIn()
我真的不知道如何将我的 SQL 转换为查询生成器。我希望当我看到查询的有效转换时,我可以理解下次我必须如何做。
以下查询生成器代码将为您提供 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()
,这将为我提供查询的字符串表示形式,该查询将由查询生成器,允许我将其与我的原始查询进行比较以确保它是相同的。
这对我有用:
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'));
我花了几天时间来了解如何将 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。我现在得到的错误:
Call to undefined method Illuminate\Database\Query\JoinClause::whereIn()
我真的不知道如何将我的 SQL 转换为查询生成器。我希望当我看到查询的有效转换时,我可以理解下次我必须如何做。
以下查询生成器代码将为您提供 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()
,这将为我提供查询的字符串表示形式,该查询将由查询生成器,允许我将其与我的原始查询进行比较以确保它是相同的。
这对我有用:
DB::table('wouter_blog_posts') ->whereNotNull('published') ->where('published', 1) ->whereNotNull('published_at') ->whereRaw('
published_at
< NOW()') ->whereRaw("(SELECT count(*) FROMwouter_blog_tags
INNER JOINwouter_blog_posts_tags
ONwouter_blog_tags
.id
=wouter_blog_posts_tags
.tags_id
WHEREwouter_blog_posts_tags
.post_id
=wouter_blog_posts
.id
ANDid
IN ( '".$tagid."' )) >=1") ->orderBy('published_at', 'desc') ->skip(0) ->take(10) ->paginate($this->property('postsPerPage'));