在laravel利用联合查询时两个数据表按照某一字段排序

10 篇文章 0 订阅
6 篇文章 0 订阅

在laravel利用联合查询时两个数据表按照某一字段排序

在项目中需要把两个表的数据按照时间进行排序,需要利用mysql的两个查询

代码:

$tourist = Tourist::query()
            ->select('id', 'name as customer_name', 'created_at as time', DB::raw("2 as type, 0 as status"))
            ->when(!empty($search), function ($query) use ($search) {
                $like = '%' . $search . '%';
                $query->where('name', 'like binary', $like)
                    ->orWhere('mobile', 'like binary', $like);
            })->when(empty($search), function ($query) {
                $query->whereBetween('created_at', TimeHelper::today());
            });
 $builder = Customer::query()
     ->select('id', 'customer_name', 'register_time as time', DB::raw("1 as type, status"))
     ->where('delete_time', 0);

 if ($search) {
     $like = '%' . $search . '%';
     $builder->where(function ($query) use ($like) {
         $query->where('customer_name', 'like binary', $like)
             ->orWhere('mobile', 'like binary', $like)
             ->orWhere('email', 'like binary', $like);
     });
 } else {
     $builder->whereBetween('register_time', TimeHelper::today());
 }

 $userList = $builder->union($tourist)
     ->orderByDesc('time')
     ->offset(($page - 1) * $per_page)
     ->limit($per_page)
     ->get()->toArray();

程序解释:

  1. DB::raw("2 as type, 0 as status") 意思是:给tourist表 和customer 表添加一个虚拟的数据type(tourist为2, customer为1)表明如果id有重复可以知道这个id对应的那个表的数据记录:
    效果:
 // 说明 type=2 是tourist中的记录, type=1是customer中的记录
{
     "id": 55,
     "customer_name": "13246532066",
     "time": 1552127193,
     "type": 1,
     "status": 1
 }, {
     "id": 16,
     "customer_name": "HGH",
     "time": 1552095123,
     "type": 2,
     "status": 0,
 },
  1. 在我的使用mysql 中的like 模糊查询是,不区分大小写问题
    深入了解:
    在MySQL中,对于Column Collate其约定的命名方法如下:
    *_bin: 表示的是binary case sensitive collation,也就是说是区分大小写的
    *_cs: case sensitive collation,区分大小写
    *_ci: case insensitive collation,不区分大小写

    解决办法:

    • 修改需要进行模糊查询字段的 Collate
    • 在进行模糊查询的时候,在like的后面加个binary就可以了,适用于表的结构不易改变的情况下(以上例子用此办法)
  2. 若需要按照某一字段进行排序,需要确保排序的字段的名字相同的,如上例中的time 如果两个数据表中的字段不一样可以使用as设置别名的办法

  3. 若要使用条件查询,需要在各自的sql builder中填写对应的条件查询语句

mongoTemplate可以使用MongoDB的聚合查询功能来实现多表联合查询,然后通过sort()方法对查询结果进行排序。 以下是一个示例代码,假设我们有两个集合:users和orders。orders集合中有一个字段userId,代表该订单属于哪个用户。我们要查询所有用户的订单,并按照订单创建排序。 ``` List<AggregationOperation> operations = new ArrayList<>(); operations.add(match(Criteria.where("status").is("PAID"))); // 过滤条件 operations.add(lookup("orders", "_id", "userId", "orders")); // 连接查询orders集合,并将结果放入orders字段中 operations.add(unwind("orders")); // 拆分orders数组为多个文档 operations.add(sort(Sort.by(Sort.Direction.DESC, "orders.createTime"))); // 对订单创建排序 operations.add(group("_id", "name", "age", "avatar").addToSet("orders").as("orders")); // 聚合用户和订单信息 operations.add(sort(Sort.by(Sort.Direction.DESC, "age"))); // 对用户年龄排序 Aggregation agg = Aggregation.newAggregation(operations); mongoTemplate.aggregate(agg, "users", UserWithOrders.class); ``` 需要注意以下几点: 1. 联表查询需要使用lookup操作,第一个参数是关联集合的名称,第二个参数是本表中的关联字段,第三个参数是外表中的关联字段,第四个参数是结果字段的名称。(在这个示例中就是users和orders两个集合,以及userId字段) 2. 分页可以在sort()方法之后,使用skip()和limit()方法来实现。 3. 聚合查询会将所有有关的字段都取出来,需要在后续的处理中选择需要的字段。 4. 如果需要查询多个聚合条件,可以在List<AggregationOperation>中追加AggregationOperation对象来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值