Laravel Eloquent中status字段作为WHERE条件无结果问题排查
Laravel Eloquent WHERE 子句使用
status 字段筛选无结果的问题排查与解决 兄弟,我太懂这种明明代码看起来没问题却查不出结果的抓狂感了!你这根本不是Laravel的BUG,是踩了SQL NULL值的经典坑!
先复盘下你的问题:你用->where('upload_conversions.status', '!=', 'x')想筛选掉状态为x的记录,但无论换什么目标字符串都返回空结果,换其他字段查询就正常,后来发现是NULL值在搞鬼。
问题根源:SQL里的NULL不参与普通比较运算
SQL中的NULL是一个特殊的“未知值”,它不等于任何值(包括它自己)。当你用!=或者<>做比较时,只要字段值是NULL,这个条件的结果既不是TRUE也不是FALSE,而是UNKNOWN——数据库会把UNKNOWN当成FALSE处理,所以所有status为NULL的记录都会被过滤掉。如果你的表中大部分记录的status都是NULL,那自然查不到结果了。
解决方案
你已经找到的方法是可行的,我再给你两种写法,按需选择:
写法1:拆分两个条件(你当前的方案)
直接用where加orWhereNull把NULL值的情况包含进来:
$this->model->join('user_credentials', 'upload_conversions.user_id', '=', 'user_credentials.user_id') ->select( 'upload_conversions.id', 'upload_conversions.status', 'upload_time', 'user_credentials.user_id', DB::raw('CONCAT(user_credentials.first_name, " ", user_credentials.last_name) as user_name') ) ->where('upload_conversions.status', '!=', 'test') ->orWhereNull('upload_conversions.status') ->groupBy('upload_time') ->get();
写法2:用whereRaw合并条件(更优雅)
把两个逻辑合并成一个SQL原生条件,看起来更简洁:
$this->model->join('user_credentials', 'upload_conversions.user_id', '=', 'user_credentials.user_id') ->select( 'upload_conversions.id', 'upload_conversions.status', 'upload_time', 'user_credentials.user_id', DB::raw('CONCAT(user_credentials.first_name, " ", user_credentials.last_name) as user_name') ) ->whereRaw('upload_conversions.status != ? OR upload_conversions.status IS NULL', ['test']) ->groupBy('upload_time') ->get();
额外建议
如果你的业务场景允许,可以考虑给upload_conversions表的status字段设置一个默认值(比如空字符串''),这样后续查询就不用额外处理NULL值的情况,从根源避免这类问题~
内容的提问来源于stack exchange,提问作者bremg
相关产品推荐
相关产品推荐

