1.需求分析
很多情况下,我们会遇到类似的需求:混合型的列表再进行分类;这种情况,可以考虑java逻辑层面两个甚至更多的list相加,然后最后进行排序,但是一旦进行分页,排序可能就混乱了,这个笔者建议直接在sql里面union all多个结果集,然后对整体进行排序
2.UNION ALL 与UNION的区别
Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
Union All:对两个结果集进行并集操作,包括重复行,不进行排序;
union all的效率比union快的多,如果可以确认合并的结果集中不包含重复数据的话,那么就用union all
3.实现方案
sql代码如下
id ="getNightOptimizationOwnerServiceListByPasser" resultMap ="OwnerResultMap" parameterType ="java.util.Map" >
SELECT
union_owner.*
FROM
(SELECT
vehicle.vehicle_id,
vehicle.vehicle_type,
sys.user_mobile,
sys.user_nickname,
car.service_id,
car.user_id,
car.pin_service_code,
car.pin_leave_words,
car.pin_start_point,
car.pin_end_point,
car.pin_start_latitude,
car.pin_start_longitude,
car.pin_end_latitude,
car.pin_end_longitude,
car.pin_total_account,
car.pin_service_account,
car.pin_single_lose_account AS pin_lose_account,
car.owner_has_seats,
car.leave_off_time,
car.pin_total_distance,
car.pin_service_kinds,
car.pin_create_time
FROM
yivi_pin_car_service car
INNER JOIN yivi_vehicle_info vehicle ON car.user_id = vehicle.user_id
AND vehicle.vehicle_identity_status = 1
INNER JOIN yivi_sys_user sys ON sys.user_id = car.user_id
AND sys.user_vehicle_identity = 1
WHERE
car.pin_publish_role = 1
AND car.service_enable = 1
AND car.service_status = 1
AND car.pin_is_visible = 1
AND car.pin_time_out = 0
test ="pinServiceKinds != null and pinServiceKinds != '' " > AND car.pin_service_kinds = #{pinServiceKinds}
test ="pinServiceKinds != null and pinServiceKinds != 3 and startLatitude != null and startLongitude != null and endLatitude != null and endLongitude != null" >
AND ROUND(
6378.138 * 2 * asin(
sqrt(
pow(
sin(
(
car.pin_start_latitude * pi() / 180 - #{startLatitude} * pi() / 180
) / 2
),
2
) + cos(car.pin_start_latitude * pi() / 180) * cos(#{startLatitude} * pi() / 180) * pow(
sin(
(
car.pin_start_longitude * pi() / 180 - #{startLongitude} * pi() / 180
) / 2
),
2
)
)
)
,
2
) < = 100
AND ROUND (
6378.138 * 2 * asin(
sqrt(
pow(
sin(
(
car.pin_end_latitude * pi() / 180 - #{endLatitude} * pi() / 180
) / 2
),
2
) + cos(car.pin_end_latitude * pi() / 180) * cos(#{endLatitude} * pi() / 180) * pow(
sin(
(
car.pin_end_longitude * pi() / 180 - #{endLongitude} * pi() / 180
) / 2
),
2
)
)
)
,
2
) < = 100
test ="pinServiceKinds == 3 " >
test ="startLatitude != null and startLongitude != null" >
AND ROUND(
6378.138 * 2 * asin(
sqrt(
pow
(
sin(
(
car.pin_start_latitude * pi() / 180 - #{startLatitude} * pi() / 180
) / 2
),
2
) + cos(car.pin_start_latitude * pi() / 180) * cos(#{startLatitude} * pi() / 180) * pow(
sin(
(
car.pin_start_longitude * pi() / 180 - #{startLongitude} * pi() / 180
) / 2
),
2
)
)
)
,
2
) < = 40
test ="endLatitude != null and endLongitude != null " >
AND ROUND(
6378.138 * 2 * asin(
sqrt(
pow(
sin(
(
car.pin_end_latitude * pi() / 180 - #{endLatitude} * pi() / 180
) / 2
),
2
) + cos(car.pin_end_latitude * pi() / 180) * cos(#{endLatitude} * pi() / 180) * pow(
sin(
(
car.pin_end_longitude * pi() / 180 - #{endLongitude} * pi() / 180
) / 2
),
2
)
)
)
,
2
) < = 40
test ="leaveOffTime != null " >
and date_format(car.leave_off_time,'%Y-%m-%d')= date_format(#{leaveOffTime},'%Y-%m-%d')
test ="leftLeaveOffTime!= null " >
and UNIX_TIMESTAMP(car. leave_off_time) > = UNIX_TIMESTAMP(date_format(#{leftLeaveOffTime},'%Y-%m-%d %H:%i'))
test ="rightLeaveOffTime!= null " >
and UNIX_TIMESTAMP(car. leave_off_time) < = UNIX_TIMESTAMP(date_format(#{rightLeaveOffTime},'%Y-%m-%d %H:%i'))
test ="vehicleType != null and vehicleType != 0" >
and vehicle.vehicle_type = #{vehicleType}
test ="pinServiceKinds != null and pinServiceKinds == 1" >
UNION
SELECT
vehicle.vehicle_id,
vehicle.vehicle_type,
sys.user_mobile,
sys.user_nickname,
car.service_id,
car.user_id,
car.pin_service_code,
car.pin_leave_words,
car.pin_start_point,
car.pin_end_point,
car.pin_start_latitude,
car.pin_start_longitude,
car.pin_end_latitude,
car.pin_end_longitude,
car.pin_total_account,
car.pin_service_account,
car.pin_single_lose_account AS pin_lose_account,
car.owner_has_seats,
car.leave_off_time,
car.pin_total_distance,
car.pin_service_kinds,
car.pin_create_time
FROM
yivi_pin_car_service car
INNER JOIN yivi_vehicle_info vehicle ON car.user_id = vehicle.user_id
AND vehicle.vehicle_identity_status = 1
INNER JOIN yivi_sys_user sys ON sys.user_id = car.user_id
AND sys.user_vehicle_identity = 1
WHERE
car.pin_publish_role = 1
AND car.service_enable = 1
AND car.service_status = 1
AND car.pin_is_visible = 1
AND car.pin_time_out = 0
AND car.pin_service_kinds = 2
AND car.pin_total_distance > 100
test ="pinServiceKinds != null and pinServiceKinds == 3" >
UNION
SELECT
vehicle.vehicle_id,
vehicle.vehicle_type,
sys.user_mobile,
sys.user_nickname,
car.service_id,
car.user_id,
car.pin_service_code,
car.pin_leave_words,
car.pin_start_point,
car.pin_end_point,
car.pin_start_latitude,
car.pin_start_longitude,
car.pin_end_latitude,
car.pin_end_longitude,
car.pin_total_account,
car.pin_service_account,
car.pin_single_lose_account AS pin_lose_account,
car.owner_has_seats,
car.leave_off_time,
car.pin_total_distance,
car.pin_service_kinds,
car.pin_create_time
FROM
yivi_pin_car_service car
INNER JOIN yivi_vehicle_info vehicle ON car.user_id = vehicle.user_id
AND vehicle.vehicle_identity_status = 1
INNER JOIN yivi_sys_user sys ON sys.user_id = car.user_id
AND sys.user_vehicle_identity = 1
WHERE
car.pin_publish_role = 1
AND car.service_enable = 1
AND car.service_status = 1
AND car.pin_is_visible = 1
AND car.pin_time_out = 0
AND car.pin_service_kinds = 2
AND car.pin_total_distance < 100
) union_owner
ORDER BY union_owner.leave_off_time ASC
LIMIT ${pageNo},
${pageSize}
4.使用注意事项
①.所有查询中的列数和列的顺序必须相同;
②.对应项的数据类型必须兼容;
好了,欢迎加入博主技术交流群,群号:313145288