好的经过数小时的研究并仍在使用DB :: select我不得不问这个问题。因为我即将把我的电脑拉开;)。
我想获取用户的最后一个输入(基于时间戳)。我可以使用raw sql
来做到这一点SELECT c.*, p.*
FROM users c INNER JOIN
(
SELECT user_id,
MAX(created_at) MaxDate
FROM `catch-text`
GROUP BY user_id
) MaxDates ON c.id = MaxDates.user_id INNER JOIN
`catch-text` p ON MaxDates.user_id = p.user_id
AND MaxDates.MaxDate = p.created_at
我从stackoverflow上的另一个帖子here获得了此查询。
我已尝试使用Laravel中的流畅查询构建器完成所有操作,但没有成功。
我知道手册说你可以这样做:
DB::table('users')
->join('contacts', function($join)
{
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
但这没有多大帮助,因为我不知道如何在那里使用子查询? 谁能点亮我的一天?
答案 0 :(得分:129)
对你们所有人来说,绝望地到达这里寻找同样的问题。我希望你能比我更快找到它; O。
这是如何解决的。 JoostK在github告诉我“加入的第一个参数是你加入的表格(或数据)。”他是对的。
这是代码。不同的表和名称,但你会得到这个想法吗?它t
DB::table('users')
->select('first_name', 'TotalCatches.*')
->join(DB::raw('(SELECT user_id, COUNT(user_id) TotalCatch,
DATEDIFF(NOW(), MIN(created_at)) Days,
COUNT(user_id)/DATEDIFF(NOW(), MIN(created_at))
CatchesPerDay FROM `catch-text` GROUP BY user_id)
TotalCatches'),
function($join)
{
$join->on('users.id', '=', 'TotalCatches.user_id');
})
->orderBy('TotalCatches.CatchesPerDay', 'DESC')
->get();
答案 1 :(得分:16)
我正在寻找一个相关问题的解决方案:找到每组的最新记录,这是典型的greatest-n-per-group的特殊化,N = 1。
解决方案涉及您在此处理的问题(即,如何在Eloquent中构建查询),因此我发布它,因为它可能对其他人有帮助。它演示了一种更简洁的子查询构造方式,使用强大的Eloquent流畅接口,多个连接列和model.optimizer = tf.train.GradientDescentOptimizer(learning_rate=initial_learning_rate)
条件在连接的子选择内。
在我的示例中,我想获取optimizer.minimize()
标识的每个组的最新DNS扫描结果(表@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateCustomers(@PathParam("id") Long id,
CustomersEntity customer){
CustomersEntity existCustomer = customerService.findOne(id);
if (existCustomer == null){
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
else {
existCustomer.setFirstname(customer.getFirstname());
existCustomer.setLastname(customer.getLastname());
existCustomer.setEmail(customer.getEmail());
existCustomer.setDateborn(customer.getDateborn());
existCustomer.setPass(customer.getPass());
customerService.update(customer);
}
return Response.noContent().build();
}
)。我单独构建子查询。
我希望Eloquent生成的SQL:
where
我是按照以下方式做到的:
scan_dns
更新:
自Laravel 5.6.17添加了sub-query joins以来,就有了一种构建查询的原生方式。
watch_id
答案 2 :(得分:2)
使用Laravel中的子查询进行查询
$resortData = DB::table('resort')
->leftJoin('country', 'resort.country', '=', 'country.id')
->leftJoin('states', 'resort.state', '=', 'states.id')
->leftJoin('city', 'resort.city', '=', 'city.id')
->select('resort.*', 'country.name as country_name', 'states.name as state_name','city.name as city_name', DB::raw("(SELECT GROUP_CONCAT(amenities.name) from resort_amenities LEFT JOIN amenities on amenities.id= resort_amenities.amenities_id WHERE resort_amenities.resort_id=resort.id) as amenities_name"))->groupBy('resort.id')
->orderBy('resort.id', 'DESC')
->get();
答案 3 :(得分:2)
我认为您正在寻找的是“ joinSub”。 laravel ^ 5.6支持。如果您使用的是低于5.6的laravel版本,则还可以在应用服务提供商文件中将其注册为宏。像这样https://github.com/teamtnt/laravel-scout-tntsearch-driver/issues/171#issuecomment-413062522
$subquery = DB::table('catch-text')
->select(DB::raw("user_id,MAX(created_at) as MaxDate"))
->groupBy('user_id');
$query = User::joinSub($subquery,'MaxDates',function($join){
$join->on('users.id','=','MaxDates.user_id');
})->select(['users.*','MaxDates.*']);
答案 4 :(得分:1)
我无法发表评论,因为我的声誉不够高。 @Franklin Rivero如果您使用的是Laravel 5.2,则可以使用setBindings方法在主查询而不是连接上设置绑定。
所以@ ph4r05答案中的主要查询看起来像这样:
$q = DnsResult::query()
->from($dnsTable . ' AS s')
->join(
DB::raw('(' . $qqSql. ') AS ss'),
function(JoinClause $join) {
$join->on('s.watch_id', '=', 'ss.watch_id')
->on('s.last_scan_at', '=', 'ss.last_scan');
})
->setBindings($subq->getBindings());
答案 5 :(得分:1)
您可以使用以下插件来处理laravel 5.5+中所有与子查询相关的功能
https://github.com/maksimru/eloquent-subquery-magic
User::selectRaw('user_id,comments_by_user.total_count')->leftJoinSubquery(
//subquery
Comment::selectRaw('user_id,count(*) total_count')
->groupBy('user_id'),
//alias
'comments_by_user',
//closure for "on" statement
function ($join) {
$join->on('users.id', '=', 'comments_by_user.user_id');
}
)->get();
答案 6 :(得分:1)
我使用的是Laravel 7.25,但我不知道它是否在以前的版本中受支持,但还不错。
public function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)
显示/获取用户ID以及他们的帖子总数,使两个表的用户和帖子保持连接状态。
return DB::table('users')
->joinSub('select user_id,count(id) noOfPosts from posts group by user_id', 'totalPosts', 'users.id', '=', 'totalPosts.user_id', 'left')
->select('users.name', 'totalPosts.noOfPosts')
->get();
如果您不想为leftjoin提及“ left”,则可以使用另一个预建函数
public function leftJoinSub($query, $as, $first, $operator = null, $second = null)
{
return $this->joinSub($query, $as, $first, $operator, $second, 'left');
}
是的,它实际上调用了相同的函数,但它本身传递了联接类型。您可以将相同的逻辑应用于其他联接,例如righJoinSub(...)等。