
場景:
希望使用phoenix做查詢服務,給服務端提供接口
設計:
通過springboot做restful的接口發布,通過mybatis做phoenix的sql處理,因此是springboot+mybatis+phoenix的集成方案;
但是會遇到一個坑!
=========================================我是華麗的分割線=====================================================
先簡單匯報下場景:
做網約車的預約單查詢處理,如圖:

這里面需要使用一個時間窗口查詢6種時間:推送訂單時間、有效搶單時間、搶單成功時間、取消訂單時間、達到目的地時間、支付時間
這里可能遇到一個問題:跨天支付!
因此為了解決跨天支付,需要在處理好的基表基礎上做6次查詢 ,分別對應不同的查詢時間,然后做union處理,最后在求和(注意:就是在最后在求和的地方出錯!!!!!)
先看下有問題的代碼:
<select id="searchContext" resultType="com.df.entity.SearchInfo"> SELECT TB."driver_id", TB."driver_name"", TB."mobile", TB."alliance_name", TB."register_city", TB."driver_type", SUM(TB."pushOrderNum") AS "pushOrderNum" , SUM(TB."effectiveSlogan") AS "effectiveSlogan", SUM(TB."grab_sus_order") AS "grab_sus_order", SUM(TB."cancel_order_num") AS "cancel_order_num", SUM(TB."cancel_passenger_num") AS "cancel_passenger_num", SUM(TB."cancel_driver_num") AS "cancel_driver_num", SUM(TB."cancel_service_num") AS "cancel_service_num", SUM(TB."destination_reached_num") AS "destination_reached_num", SUM(TB."pay_num") AS "pay_num", SUM(TB."order_cumulative_num") AS "order_cumulative_num", SUM(TB."order_pay_cumulative_num") AS "order_pay_cumulative_num" FROM ( SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(to_number("pushOrderNum")) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "pushOrderTime" != '0' THEN TO_DATE("pushOrderTime",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("pushOrderTime",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''" > and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''" > and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''" > and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''" > and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''" > and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''" > and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(to_number("effectiveSlogan")) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "_effective_glab_time" != '0' THEN TO_DATE("_effective_glab_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("_effective_glab_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''" > and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''" > and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''" > and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''" > and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''" > and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''" > and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(to_number("grab_sus_order")) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "grab_sus_time" != '0' THEN TO_DATE("grab_sus_time" , 'yyyy-MM-dd') >= TO_DATE(#{start_time} , 'yyyy-MM-dd') AND TO_DATE("grab_sus_time" , 'yyyy-MM-dd') <= TO_DATE(#{end_time} , 'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''" > and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''" > and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''" > and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''" > and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''" > and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''" > and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(to_number("cancel_order_num")) AS "cancel_order_num", sum(to_number("cancel_passenger_num")) AS "cancel_passenger_num", sum(to_number("cancel_driver_num")) AS "cancel_driver_num", sum(to_number("cancel_service_num")) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "cancel_time" != '0' THEN TO_DATE("cancel_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("cancel_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''" > and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''" > and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''" > and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''" > and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''" > and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''" > and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(to_number("destination_reached_num")) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "close_gps_time" != '0' THEN TO_DATE("close_gps_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("close_gps_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''" > and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''" > and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''" > and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''" > and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''" > and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''" > and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(to_number("pay_num")) AS "pay_num" , sum(to_number("order_cumulative_num")) AS "order_cumulative_num", sum(to_number("order_pay_cumulative_num")) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "pay_time" != '0' THEN TO_DATE("pay_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("pay_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''" > and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''" > and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''" > and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''" > and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''" > and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''" > and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" ) as TB GROUP BY TB."driver_id" , TB."driver_name" , TB."mobile" , TB."alliance_name" , TB."register_city" , TB."driver_type" </select>
這段代碼大概就是:
select tb."driver_id" ... , sum(xxx1) , sum(xxx2) , ..... from ( A union B union C union D union E union F union G ) as tb group by tb."driver_id" ...
這種操作的問題就在於:使用mybatis做union后,生成了一張表tb , 按照phoenix的官方說法是,phoenix嚴格區別大小寫的,因此我們做完phoenix后,習慣性的在字段上加上雙引號;
但是如果是使用mybatis做了集成后,union生成的表名稱和字段名稱,是不需要也不能在區分大小寫的,因此在加雙引號,就會出現字段找不到等一系列錯誤
解決后的代碼:
<select id="searchContext" resultType="com.df.entity.SearchInfo"> SELECT "TB1".driver_id, "TB1".driver_name, "TB1".mobile, "TB1".alliance_name, "TB1".register_city, "TB1".driver_type, SUM("TB1".pushOrderNum) AS "pushOrderNum" , SUM("TB1".effectiveSlogan) AS "effectiveSlogan", SUM("TB1".grab_sus_order) AS "grab_sus_order", SUM("TB1".cancel_order_num) AS "cancel_order_num", SUM("TB1".cancel_passenger_num) AS "cancel_passenger_num", SUM("TB1".cancel_driver_num) AS "cancel_driver_num", SUM("TB1".cancel_service_num) AS "cancel_service_num", SUM("TB1".destination_reached_num) AS "destination_reached_num", SUM("TB1".pay_num) AS "pay_num", SUM("TB1".order_cumulative_num) AS "order_cumulative_num", SUM("TB1".order_pay_cumulative_num) AS "order_pay_cumulative_num" from (SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(to_number("pushOrderNum")) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "pushOrderTime" != '0' THEN TO_DATE("pushOrderTime",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("pushOrderTime",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''"> and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''"> and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''"> and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''"> and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''"> and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''"> and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(to_number("effectiveSlogan")) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "_effective_glab_time" != '0' THEN TO_DATE("_effective_glab_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("_effective_glab_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''"> and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''"> and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''"> and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''"> and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''"> and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''"> and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(to_number("grab_sus_order")) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "grab_sus_time" != '0' THEN TO_DATE("grab_sus_time" , 'yyyy-MM-dd') >= TO_DATE(#{start_time} , 'yyyy-MM-dd') AND TO_DATE("grab_sus_time" , 'yyyy-MM-dd') <= TO_DATE(#{end_time} , 'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''"> and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''"> and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''"> and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''"> and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''"> and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''"> and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(to_number("cancel_order_num")) AS "cancel_order_num", sum(to_number("cancel_passenger_num")) AS "cancel_passenger_num", sum(to_number("cancel_driver_num")) AS "cancel_driver_num", sum(to_number("cancel_service_num")) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "cancel_time" != '0' THEN TO_DATE("cancel_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("cancel_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''"> and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''"> and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''"> and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''"> and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''"> and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''"> and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(to_number("destination_reached_num")) AS "destination_reached_num" , sum(0) AS "pay_num" , sum(0) AS "order_cumulative_num", sum(0) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "close_gps_time" != '0' THEN TO_DATE("close_gps_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("close_gps_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''"> and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''"> and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''"> and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''"> and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''"> and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''"> and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" union all SELECT "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" , sum(0) AS "pushOrderNum" , sum(0) AS "effectiveSlogan" , sum(0) AS "grab_sus_order" , sum(0) AS "cancel_order_num", sum(0) AS "cancel_passenger_num", sum(0) AS "cancel_driver_num", sum(0) AS "cancel_service_num" , sum(0) AS "destination_reached_num" , sum(to_number("pay_num")) AS "pay_num" , sum(to_number("order_cumulative_num")) AS "order_cumulative_num", sum(to_number("order_pay_cumulative_num")) AS "order_pay_cumulative_num" FROM "_crontab_reservation" WHERE CASE WHEN "pay_time" != '0' THEN TO_DATE("pay_time",'yyyy-MM-dd') >= TO_DATE(#{start_time},'yyyy-MM-dd') AND TO_DATE("pay_time",'yyyy-MM-dd') <= TO_DATE(#{end_time},'yyyy-MM-dd') ELSE 1=1 END <if test="driver_id != null and driver_id !=''"> and "driver_id"= #{driver_id} </if> <if test="driver_name != null and driver_name !=''"> and "driver_name" = #{driver_name} </if> <if test="mobile != null and mobile !=''"> and "mobile" = #{mobile} </if> <if test="alliance_name != null and alliance_name !=''"> and "driver_management_id" = #{alliance_name} </if> <if test="register_city != null and register_city !=''"> and substr("register_city" , 0 , 4) = substr(#{register_city} , 0 , 4) </if> <if test="driver_type != null and driver_type !=''"> and "driver_type" = #{driver_type} </if> GROUP BY "driver_id" , "driver_name" , "mobile" , "alliance_name" , "register_city" , "driver_type" ) AS "TB1" GROUP BY "TB1".driver_id , "TB1".driver_name , "TB1".mobile , "TB1".alliance_name , "TB1".register_city , "TB1".driver_type </select>
