Laravel Fluent查询生成器join子查询
好吧,经过几个小时的研究,仍然使用DB :: select我不得不问这个问题。 因为我即将通过我的电脑了;)。
我想获得用户的最后input(基于时间戳)。 我可以做到这一点与原始的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
我从另一个post得到了这个查询在stackoverflow。
我已经尽了一切努力做到这一点在Laravelstream利的查询生成器,但没有成功。
我知道手册说你可以这样做:
DB::table('users') ->join('contacts', function($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...); }) ->get();
但是这并没有什么帮助,因为我没有看到如何在那里使用子查询? 任何人都可以照亮我的一天?
好吧,你们所有人都在这里绝望地寻找同样的问题。 我希望你能更快地find我所做的; O。
这是如何解决的。 JoostK在github上告诉我,“join的第一个参数是你join的表(或数据)”。 他是对的。
这是代码。 不同的表格和名称,但你会得到正确的想法? 它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();
我正在寻找一个相当相关的问题的解决scheme:find每个组的最新logging,这是N = 1的典型最大n组的专业化。
解决scheme涉及到你在这里处理的问题(即如何在Eloquent中build立查询),所以我发布它,因为它可能对别人有帮助。 它演示了一个更清晰的子查询构build方式,使用强大的Eloquent fluent接口和多个连接列,并且里面的条件join了子select。
在我的示例中,我想获取由watch_id
标识的每个组的最新DNS扫描结果(表scan_dns
)。 我分别build立子查询。
我想要雄辩生成的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`
我是这样做的:
// 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();
在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();