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

Laravel原生查询返回空数组,phpMyAdmin执行同查询有结果

解决Laravel执行原生IN查询返回空数组的问题

这个问题我之前也碰到过,核心问题出在你对Laravel参数绑定的理解上——你把多个手机号拼成了一个字符串当作单个参数传入,这就导致SQL执行时的逻辑和你在phpMyAdmin里直接跑的不一样了。

问题根源

你拼接出来的字符串'+1234567819','+19873216154','+15984989898',当通过DB::select绑定参数时,Laravel会把它当作单个完整的值包裹在引号里,最终执行的SQL其实是:

SELECT id, reply_text, sending_time FROM sms_sender_inbox_replies 
WHERE phone_number IN ('\'1234567819\',\'19873216154\',\'15984989898\'') 
AND id IN ( SELECT MAX( id ) FROM sms_sender_inbox_replies GROUP BY phone_number )

相当于你在找一个等于'+1234567819','+19873216154','+15984989898'的手机号,自然匹配不到任何结果。

两种可行的解决方案

方案一:用Laravel查询构造器构建查询(推荐)

Laravel的查询构造器会自动处理whereIn的参数绑定,不需要手动拼接,代码更安全也更易维护:

$phone_numbers = ['+1234567819', '+19873216154', '+15984989898'];

$results = DB::connection('second_connection')
    ->table('sms_sender_inbox_replies')
    ->select('id', 'reply_text', 'sending_time')
    ->whereIn('phone_number', $phone_numbers)
    ->whereIn('id', function ($subQuery) {
        $subQuery->selectRaw('MAX(id)')
                 ->from('sms_sender_inbox_replies')
                 ->groupBy('phone_number');
    })
    ->get();

方案二:手动生成占位符的原生SQL绑定

如果坚持用原生SQL,需要为每个手机号生成独立的占位符,再把数组作为参数传入:

$phone_numbers = ['+1234567819', '+19873216154', '+15984989898'];
// 根据手机号数量生成对应数量的?占位符
$placeholders = implode(',', array_fill(0, count($phone_numbers), '?'));

$sql = <<<SQL
SELECT id, reply_text, sending_time FROM sms_sender_inbox_replies 
WHERE phone_number IN ($placeholders) 
AND id IN ( SELECT MAX( id ) FROM sms_sender_inbox_replies GROUP BY phone_number )
SQL;

$results = DB::connection('second_connection')->select($sql, $phone_numbers);

验证效果

调整后查看查询日志,你会看到每个手机号都是单独的参数,而不是拼接成一个字符串,这样SQL逻辑就和你在phpMyAdmin里执行的完全一致,就能正确返回那3条结果了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:34:51