Laravel5.5 中模型查询时设置的别名与 DB::raw 冲突了,怎样让别名不加表前缀?

需求:用户列表中,需要同时显示用户首次消费的时间及金额,于是写了如下查询:

$users = DB::table('users')
->select(['users.id', 'users.name', 'o.real_amount', DB::raw('MIN(o.created_at) AS order_at')])
->join('orders as o', 'o.user_id', '=', 'users.id')
->whereIn('users.id', [3,4])
->get();

参考了 stockoverflow 中的答案,写的
但是实际调用时,发现所有的别名,都自动加上了表前缀,这样就导致了 DB::raw 中,字段不匹配的错误;输入的SQL如下:

select `pk_users`.`id`, `pk_users`.`name`, `pk_o`.`real_amount`, 
MIN(o.created_at) AS order_at 
from `pk_users` 
inner join `pk_orders` as `pk_o` on `pk_o`.`user_id` = `pk_users`.`id` 
where `pk_users`.`id` in (3, 4)

造成了这样一个错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'o.created_at' in 'field list' 

请问,这种错误该如何处理,真的要手动给 DB::raw() 中的 o.created_at 改为 pk_o.created_at 吗?
意外查到,说这种方式,效率非常慢,那还有其它更好的实现这种需求的写法吗?
比如,分开查询,先查询用户数据,然后再查询订单数据,之后再用一个foreach将两个数据关联起来?

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

看到楼主在思否上面的提问,找到了解决办法 DB::raw('CONCAT('.DB::getTablePrefix().'rel.name, "=", '.DB::getTablePrefix().'rel.real_name) as name')

3年前 评论
讨论数量: 13

DB::raw() 中使用了 min, 但是 min 获取最小值,不能扩展到整行记录,所以,获取用户列表中,每个用户的首次消费时间,但是获取到的金额确实错误的;
有点儿怀疑,MySQL 的 min 函数究竟有什么用,又不能扩展到整条记录

6年前 评论

通过这种方式实现了:

        $users = DB::select(
            'SELECT u.name,u.guide_id,u.shop_id,u.merchant_id,o.id,o.real_amount,o.created_at
            FROM `pk_orders` o
            JOIN
            (SELECT user_id,MIN(created_at) minCreated
            FROM `pk_orders` GROUP BY user_id) r
            ON o.created_at=r.minCreated AND o.user_id=r.user_id
            LEFT JOIN `pk_users` u ON u.id=o.user_id
            WHERE o.user_id IN ('.implode(',', [3,4]).')'
        );

希望可以有更好的实现方式

6年前 评论

楼主试试这个:

$users = DB::table('users')
->select(['users.id', 'users.name', 'o.real_amount')
->min(o.created_at as order_at)
->join('orders as o', 'o.user_id', '=', 'users.id')
->whereIn('users.id', [3,4])
->get();
6年前 评论

min('o.created_at as order_at')

6年前 评论

报什么错误?

6年前 评论

@leoyang 不行的!用了 min 就不能用 get,而且 min 只能返回其参数中指定那个字段,不能扩展到整条记录

6年前 评论

@leoyang
这样行不通的
file
你能帮我把#2中的写法,改成 Eloquent ORM 实现吗?

6年前 评论
$users = DB::select(['u.name','u.guide_id',u.'shop_id','u.merchant_id','o.id','o.real_amount','o.created_at'])
->from('orders as o')
->join(Expression(SELECT user_id,MIN(created_at) minCreated FROM `pk_orders` GROUP BY user_id) r),function($query) {
$query->on('pk_o.created_at','r.minCreated')->on('pk_o.user_id','r.user_id')
})->leftJoin('pk_users as u',' u.id','o.user_id')->whereIn(' o.user_id',[3,4])
6年前 评论

可能会报错,你调一下吧,打一下sql

6年前 评论

楼主,怎么解决的啊 同样遇到这样的问题 用CONCAT也报错,请大神分享经验

3年前 评论

看到楼主在思否上面的提问,找到了解决办法 DB::raw('CONCAT('.DB::getTablePrefix().'rel.name, "=", '.DB::getTablePrefix().'rel.real_name) as name')

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!