dri*_*hel 65 laravel laravel-4
好的经过几个小时的研究并仍在使用DB :: select我不得不问这个问题.因为我即将把我的电脑拉下来;).
我想得到用户的最后一个输入(基于时间戳).我可以使用原始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
Run Code Online (Sandbox Code Playgroud)
我从另一个帖子此查询这里的计算器.
我已尝试使用Laravel中的流畅查询构建器完成所有操作,但没有成功.
我知道手册说你可以这样做:
DB::table('users')
->join('contacts', function($join)
{
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
Run Code Online (Sandbox Code Playgroud)
但这没有多大帮助,因为我不知道如何在那里使用子查询?谁可以点亮我的一天?
dri*_*hel 133
对你们所有人来说,绝望地到达这里寻找同样的问题.我希望你能比我更快找到它; O.
这是如何解决的.JoostK在github告诉我"加入的第一个参数是你加入的表格(或数据)." 而他是对的.
这是代码.不同的表和名称,但你会得到这个想法吗?它
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();
Run Code Online (Sandbox Code Playgroud)
ph4*_*r05 20
我正在寻找一个相关问题的解决方案:找到每组的最新记录,这是N = 1 的典型最大n组的特化.
解决方案涉及到您在此处理的问题(即,如何在Eloquent中构建查询),因此我发布它可能对其他人有帮助.它演示了一种更简洁的子查询构造方式,它使用强大的Eloquent流畅接口,具有多个连接列和where连接子选择内的条件.
在我的示例中,我想获取scan_dns每个组标识的最新DNS扫描结果(表)watch_id.我分别构建子查询.
我希望Eloquent生成的SQL:
SELECT * FROM `scan_dns` AS `s`
INNER JOIN (
SELECT x.watch_id, MAX(x.last_scan_at) as last_scan
FROM `scan_dns` AS `x`
WHERE `x`.`watch_id` IN (1,2,3,4,5,42)
GROUP BY `x`.`watch_id`) AS ss
ON `s`.`watch_id` = `ss`.`watch_id` AND `s`.`last_scan_at` = `ss`.`last_scan`
Run Code Online (Sandbox Code Playgroud)
我是通过以下方式完成的:
// table name of the model
$dnsTable = (new DnsResult())->getTable();
// groups to select in sub-query
$ids = collect([1,2,3,4,5,42]);
// sub-select to be joined on
$subq = DnsResult::query()
->select('x.watch_id')
->selectRaw('MAX(x.last_scan_at) as last_scan')
->from($dnsTable . ' AS x')
->whereIn('x.watch_id', $ids)
->groupBy('x.watch_id');
$qqSql = $subq->toSql(); // compiles to SQL
// the main query
$q = DnsResult::query()
->from($dnsTable . ' AS s')
->join(
DB::raw('(' . $qqSql. ') AS ss'),
function(JoinClause $join) use ($subq) {
$join->on('s.watch_id', '=', 'ss.watch_id')
->on('s.last_scan_at', '=', 'ss.last_scan')
->addBinding($subq->getBindings());
// bindings for sub-query WHERE added
});
$results = $q->get();
Run Code Online (Sandbox Code Playgroud)
更新:
从Laravel 5.6.17开始,添加了子查询连接,因此有一种本机方式来构建查询.
$latestPosts = DB::table('posts')
->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
->where('is_published', true)
->groupBy('user_id');
$users = DB::table('users')
->joinSub($latestPosts, 'latest_posts', function ($join) {
$join->on('users.id', '=', 'latest_posts.user_id');
})->get();
Run Code Online (Sandbox Code Playgroud)
我认为您正在寻找的是“ 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.*']);
Run Code Online (Sandbox Code Playgroud)
小智 7
我使用的是 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();
Run Code Online (Sandbox Code Playgroud)
如果您不想为 leftjoin 提及“left”,那么您可以使用另一个预构建函数
public function leftJoinSub($query, $as, $first, $operator = null, $second = null)
{
return $this->joinSub($query, $as, $first, $operator, $second, 'left');
}
Run Code Online (Sandbox Code Playgroud)
是的,它实际上调用了相同的函数,但它传递了连接类型本身。您可以对其他连接应用相同的逻辑,即 rightJoinSub(...) 等。
在 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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
70874 次 |
| 最近记录: |