目前有这样两个需求:
1) 查询用户,显示用户的信息以及他写过的书籍。如果用户有书籍,则显示,最多显示2本。如果没有,则不显示书籍。
2) 显示用户的id号以及对应的书籍件数(只用SQL实现,不使用业务逻辑)。
本文中用到的user模型,数据,控制器,路由之类的都已经在另一篇文章 手摸手教你让Laravel开发Api更得心应手 创建好了。
users表中的数据

books表中的数据

这个比较容易,只要在关联函数限制条数即可。
1
|
php artisan make:model Models/Book
|
编辑 app/Models/User.php,添加关联函数
1
|
public function books(){
|
在app/Http/Controllers/Api/UserController.php里,随意添加一个测试函数
1
|
//关联查询限制条数
|
测试结果,符合要求,id为1的用户原来是3本书籍,现在只被取出2本。

一开始,我们会这样写SQL语句
1
|
select `u`.`id`,`u`.`name`,`u`.`num` from `users` as `u` left join (select `user_id`,count(*) as `num` from books group by `user_id`) as `b` on `u`.id = `b`.user_id
|
最后显示如下,并不会将没有的显示为0

所以我们稍加修改,用上MySQL的内置函数
1
|
select distinct `u`.`id`,`u`.`name`,IFNULL( `b`.`num`, 0 ) AS num from `users` as `u` left join (select `user_id`,count(*) as `num` from books group by `user_id`) as `b` on `u`.id = `b`.user_id
|
符合我们的需求。

写SQL很容易,那我们应该如何在框架中使用呢(不允许查完再用业务逻辑后获得答案)?同时我们再附加一个条件,只要id为1,2,3,4,5的用户。
查询Laravel手册,参考查询构造器的高级join语句,我们会立刻想到下面这样编写
1
|
public function test3(){
|
测试的时候我们发现报了错
1
|
Unknown column ‘b.number‘ in ‘field list‘ (SQL: select distinct u.id,IFNULL( b.number, 0 ) AS number from `users` as `u` left join `books` as `b` on `user_id` in (1, 2, 3, 4, 5) and `u`.`id` = `b`.`user_id` where `id` in (1, 2, 3, 4, 5))
|
最后的SQL语句跟我们想象中的不太一样。
错误的原因是,我们其实是使用left join连接了子查询,但是Laravel的联表查询,例如join,lefeJoin,rightJoin等,经过个人的测试,这些闭包并不能实现子查询的。所以最后获得的SQL语句是错误的。
Laravel官方文档的子查询并没有这方面详细的介绍,所以我们一起来了解一下其他地方查来的资料
toSql()方法的作用是为了获取不带有binding参数的SQL
例如:
1
|
select * from `users` where `users`.`id` = ?
|
getQuery()方法的作用是为了获取binding参数并代替toSql()获得SQL的问号,从而得到完整的SQL
例如:
1
|
select * from `users` where `users`.`id` = 1
|
现在我们使用Query Builder来修复一下之前的问题
1
|
public function test2(){
|
最后的结果符合我们的需求
进行许可。转载请注明出处!原文:https://www.cnblogs.com/zwwxyh/p/12061269.html