Laravel 的数据库查询构建器
Posted
技术标签:
【中文标题】Laravel 的数据库查询构建器【英文标题】:Laravel's Database Query Builder 【发布时间】:2019-06-11 15:26:33 【问题描述】:我正在尝试使用 Laravel 的数据库查询生成器编写一个 mysql 选择查询
我有这个mysql查询:
SELECT * FROM `tweets` WHERE `user_id` = 1 OR `user_id` in (SELECT `follows_id` from `follows` where `user_id` = 1)
我正在尝试为 Laravel 编写它
$users = DB::table('tweets')
->where('user_id', '=', 1)
如何做到这一点?
【问题讨论】:
查看定义关系。定义一个Tweet
模型,一个User
模型并关联它们,那么你应该可以做到$result = Tweet::whereHas("User", function($subQuery) $subQuery->where("user_id", "=", 1); )->get();
在遵循@TimLewis 的建议之前,我建议将此查询重写为SELECT * FROM tweets WHERE tweets.user_id = 1 UNION ALL SELECT * FROM tweets INNER JOIN follows ON tweets.user_id = follows.follow_id WHERE follows.user_id = 1
,因为如果性能很重要OR
和IN(SELECT ..)
往往在MySQL 中优化得有点糟糕,它会更优化。
我同意这两个 cmets,至于 @TimLewis 一个,它不起作用,因为据我从查询中了解到,他试图获得的是用户所有推文的列表AND 来自登录用户关注的用户的推文。如果我错了,请纠正我。
@nakov 是的,但这可以是一个额外的orWhereHas()
子句。由于必须猜测关系/查询逻辑,用 Laravel 术语来回答这个问题有点困难。我尽量避免使用 DB::table()
来支持模型,但你的答案应该可以正常工作。
nakov 是的,你写的正是我想要做的事情
【参考方案1】:
即使看起来很丑,你也可以这样做。
$tweets = DB::table('tweets')
->where('user_id', 1)
->orWhereIn('user_id', DB::table('follows')->select('follows_id')->where('user_id', 1)->pluck('follows_id'))
->get();
【讨论】:
【参考方案2】:我建议将 SQL 重写为 OR
和 IN(SELECT ...)
往往会优化得很差。
SQL 结果可能是错误的,因为您没有提供示例数据和预期结果,请参阅Why should I provide a Minimal Reproducible Example for a very simple SQL query? 以提供这些数据。
SELECT
tweets.*
FROM
tweets
WHERE
tweets.user_id = 1
UNION ALL
SELECT
tweets.*
FROM
tweets
INNER JOIN
follows ON tweets.user_id = follows.follows_id
WHERE
follows.user_id = 1
我相信下面的 Laraval 代码应该做到这一点。但不确定,因为我已经有一段时间没有在 Laravel 中编程了。
<?php
$first = DB::table('tweets')
->select('tweets.*')
->where('user_id', '=', 1);
$second = DB::table('tweets')
->select('tweets.*')
->join('follows', 'tweets.user_id', '=', 'follows.follows_id')
->where('follows.user_id ', '=', 1)
->union($first)
->get();
?>
【讨论】:
像魅力一样工作!以上是关于Laravel 的数据库查询构建器的主要内容,如果未能解决你的问题,请参考以下文章