Laravel union多表部署Heroku PostgreSQL报数据类型不匹配如何解决
问题根源
PostgreSQL 对 UNION 语句的约束远严格于 MySQL,要求所有参与 UNION 的子查询,相同位置的列数据类型必须完全匹配。
你的三个子查询列类型对应关系不匹配:
- shippings 子查询的第2、3列是字符串类型(
port_of_destination、booking_number) - storage_rents、car_parkings 子查询的第2、3列是日期类型(
start_date、end_of_free_charge)
本地 MySQL 做了隐式类型转换所以运行正常,PostgreSQL 直接抛出类型不匹配错误。另外你在日期字段上直接用like模糊匹配的写法,在 PostgreSQL 中也会触发类型错误。
解决方案
把前两个子查询的日期字段显式转为字符串,同时给字段别名和 shippings 子查询的列名保持一致,保证列顺序、列类型完全对齐;同时把模糊匹配的日期字段也转成字符串后再做匹配,不改动原有查询逻辑。
修改后的完整代码如下:
$storage_rent = DB::table('storage_rents') ->select( 'order_id', DB::raw("to_char(start_date, 'YYYY-MM-DD') as port_of_destination"), DB::raw("to_char(end_of_free_charge, 'YYYY-MM-DD') as booking_number"), 'orders.order_type' ) ->distinct() ->join('orders', 'storage_rents.order_id', '=', 'orders.id') ->where(DB::raw("to_char(start_date, 'YYYY-MM-DD')"), 'like', '%' . $q . '%') ->orWhere(DB::raw("to_char(end_of_free_charge, 'YYYY-MM-DD')"), 'like', '%' . $q . '%'); $car_parkings = DB::table('car_parkings') ->select( 'order_id', DB::raw("to_char(start_date, 'YYYY-MM-DD') as port_of_destination"), DB::raw("to_char(end_of_free_charge, 'YYYY-MM-DD') as booking_number"), 'orders.order_type' ) ->distinct() ->join('orders', 'car_parkings.order_id', '=', 'orders.id') ->where(DB::raw("to_char(start_date, 'YYYY-MM-DD')"), 'like', '%' . $q . '%') ->orWhere(DB::raw("to_char(end_of_free_charge, 'YYYY-MM-DD')"), 'like', '%' . $q . '%'); return DB::table('shippings') ->select('order_id', 'port_of_destination', 'booking_number', 'orders.order_type') ->distinct() ->join('orders', 'shippings.order_id', '=', 'orders.id') ->where('port_of_destination', 'like', '%' . $q . '%') ->orWhere('container_number', 'like', '%' . $q . '%') ->orWhere('booking_number', 'like', '%' . $q . '%') ->union($storage_rent) ->union($car_parkings) ->get();
修改后返回的结构和你之前本地测试的结果完全一致,不会影响原有业务逻辑。
内容的提问来源于stack exchange,提问作者chablis-omoba
相关产品推荐
相关产品推荐

