You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何用whereIn从JSON字段查找重复手机号?

解决Laravel中JSON字段查找重复手机号的问题

原代码的问题主要出在JSON字段的提取方式和子查询分组的逻辑上,以下是修正后的实现方案:

修正思路

  1. 对JSON字段的phone值进行正确提取,确保获取到不带引号的纯字符串(MySQL中可使用->>语法)
  2. 子查询中直接使用JSON提取表达式分组,避免别名导致的数据库解析问题
  3. 主查询的whereIn参数需要用DB::raw包裹,确保数据库能正确识别JSON路径表达式

修正后的代码

use Illuminate\Support\Facades\DB;

// 获取手机号重复的订单记录
$query = Order::query();
return $query->select('id', 'recipient')
    ->whereNotNull('recipient')
    ->whereIn(DB::raw("recipient->>'$.phone'"), function ($subQuery) {
        $subQuery->select(DB::raw("recipient->>'$.phone'"))
            ->from('orders')
            ->whereNotNull('recipient')
            ->groupBy(DB::raw("recipient->>'$.phone'"))
            ->havingRaw('COUNT(*) > 1');
    })->paginate();

关键说明

  • recipient->>'$.phone':MySQL专属语法,用于提取JSON字段并自动去除字符串引号,等价于JSON_UNQUOTE(JSON_EXTRACT(recipient, '$.phone')),保证获取的是纯净的手机号字符串
  • 子查询直接用JSON提取表达式分组,避免了分组阶段无法识别字段别名的问题
  • 主查询用DB::raw包裹JSON路径,让Laravel直接传递原生SQL表达式给数据库,而非当作普通字段处理

兼容PostgreSQL(可选)

如果使用PostgreSQL数据库,JSON字段提取语法需调整为recipient->>'phone',对应代码替换如下:

// PostgreSQL版本适配
->whereIn(DB::raw("recipient->>'phone'"), function ($subQuery) {
    $subQuery->select(DB::raw("recipient->>'phone'"))
        ->from('orders')
        ->whereNotNull('recipient')
        ->groupBy(DB::raw("recipient->>'phone'"))
        ->havingRaw('COUNT(*) > 1');
})

内容的提问来源于stack exchange,提问作者Leslie Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:43:24