├── README.md ├── SqlAnalysis.java └── SqlExplainByDruid.java /README.md: -------------------------------------------------------------------------------- 1 | hql-parser 2 | ========== 3 | 4 | hive sql parser 5 | 6 | 7 | 分析HQL语句到字段级别。 8 | 9 | 10 | 解析抽象语法树,一条hql被第一个关键字FROM分成2部分,前部分叫做Insert,后半部分叫做From 11 | 12 | 13 | 1. 当不指定目标表是,默认插入到tmp dir 14 | 15 | 16 | 2. From 源表有几种情况 17 | 18 | 19 | 2.1 直接FROM 表 20 | 21 | 22 | 2.2 子查询 23 | 24 | 25 | 2.3 JOIN 26 | 27 | 28 | ....递归便利获得所有表、字段。 29 | 30 | 31 | 待续. 32 | 33 | -------------------------------------------------------------------------------- /SqlAnalysis.java: -------------------------------------------------------------------------------- 1 | package smallbaby.io.cole.zhang; 2 | 3 | import org.apache.hadoop.hive.ql.lib.Node; 4 | import org.apache.hadoop.hive.ql.parse.ASTNode; 5 | import org.apache.hadoop.hive.ql.parse.HiveParser; 6 | import org.apache.hadoop.hive.ql.parse.ParseDriver; 7 | 8 | /** 9 | * SQL字段级分析,思路有了。待完善代码 10 | * @author kaizhang 11 | * 12 | */ 13 | public class SqlAnalysis { 14 | 15 | public static void main(String[] args) throws Exception { 16 | String query = "select id, name from log_info"; 17 | query="select a.id,b.name,c.addr,d.pwd,f.tel from a join b join c join d join f"; 18 | run(query); 19 | 20 | } 21 | 22 | 23 | public static void run(String query) throws Exception { 24 | ParseDriver pd = new ParseDriver(); 25 | ASTNode tree = pd.parse(query); 26 | System.out.println("************开始分析*********************\n"); 27 | analysis((ASTNode)tree.getChild(0)); 28 | System.out.println("\n************END*********************"); 29 | } 30 | 31 | 32 | /** 33 | * 分析入口 34 | * 一个query分为2部分, INSERT 和 FROM 35 | * 1. insert:不写create 和 insert into的默认插入到TMP_FILE,select部分包含在insert结构中 36 | * 2. from : 后边可能为子查询、join。单表、union 37 | * @param ast 38 | */ 39 | public static void analysis(ASTNode ast) { 40 | int len = ast.getChildCount(); 41 | if(len > 0) { 42 | for (Node n : ast.getChildren()) { 43 | ASTNode asn = (ASTNode)n; 44 | switch (asn.getToken().getType()) {//根据类型分发 45 | case HiveParser.TOK_FROM: 46 | ASTNode ASTNodetmp02 = (ASTNode)asn.getChild(0); 47 | fromAnalysis(ASTNodetmp02); 48 | break; 49 | case HiveParser.TOK_INSERT: // 分两部分,insert into and select cols 50 | // 51 | for (int i = 0; i < asn.getChildCount(); i++) { 52 | insertAnalysis((ASTNode)asn.getChild(i)); 53 | } 54 | break; 55 | case HiveParser.TOK_UNION: 56 | int childcount = asn.getChildCount(); 57 | for (int childpos = 0; childpos < childcount; ++childpos) { 58 | analysis((ASTNode)asn.getChild(childpos)); 59 | } 60 | break; 61 | } 62 | } 63 | } else { 64 | System.out.println(ast.getText()); 65 | } 66 | } 67 | 68 | /** 69 | * 子查询分析 70 | * @param subQuery 71 | */ 72 | public static void subQueryAnalysis(ASTNode subQuery) { 73 | 74 | int cc = 0; 75 | int cp = 0; 76 | 77 | switch (subQuery.getToken().getType()) { 78 | case HiveParser.TOK_QUERY: 79 | cc = subQuery.getChildCount(); 80 | 81 | for ( cp = 0; cp < cc; ++cp) { 82 | ASTNode atmp = (ASTNode)subQuery.getChild(cp); 83 | 84 | switch (atmp.getToken().getType()) { 85 | case HiveParser.TOK_FROM: 86 | fromAnalysis( (ASTNode)atmp.getChild(0)); 87 | break; 88 | } 89 | } 90 | break; 91 | case HiveParser.TOK_UNION: 92 | cc = subQuery.getChildCount(); 93 | 94 | for ( cp = 0; cp < cc; ++cp) { 95 | subQueryAnalysis( (ASTNode)subQuery.getChild(cp)); 96 | } 97 | break; 98 | } 99 | } 100 | 101 | /** 102 | * insert部分分析 103 | * 1. TOK_DESTINATION 为目标表,不限定时,默认为tok_dir/tmp_file 104 | * 2. TOK_SELECT 为 select部分 105 | * @param ast 106 | */ 107 | public static void insertAnalysis(ASTNode ast) { 108 | switch(ast.getToken().getType()) { 109 | case HiveParser.TOK_DESTINATION: 110 | if(ast.getChild(0).getType() == 616) {// tok dir 111 | System.out.println("* Insert Table:\t" + ast.getChild(0).getChild(0).getText()); 112 | } else { 113 | System.out.println("* Insert Table:\t" + ast.getChild(0).getChild(0).getChild(0).getText()); 114 | } 115 | break; 116 | case HiveParser.TOK_SELECT: 117 | int len = ast.getChildCount(); 118 | for (int i = 0; i < len; i++) { 119 | ASTNode astmp = (ASTNode)ast.getChild(i); 120 | if(astmp.getChild(0).getType() == HiveParser.TOK_TABLE_OR_COL) { 121 | System.out.println("* Select Cols :\t" + astmp.getChild(0).getChild(0).getText()); 122 | } else if(astmp.getChild(0).getType() == HiveParser.TOK_ALLCOLREF){ // select * 123 | 124 | String co = null; 125 | try { 126 | if(astmp.getChild(0).getChild(0).getType() == HiveParser.TOK_TABNAME) { 127 | co = astmp.getChild(0).getChild(0).getChild(0).getText() + ".*"; 128 | } else { 129 | co = astmp.getChild(0).getChild(0).getChild(0).getText(); 130 | } 131 | }catch(Exception e) { 132 | co = "*"; 133 | } 134 | System.out.println("* Select Cols :\t" + co); 135 | } else { 136 | System.out.println("* Select Cols :\t" + astmp.getChild(0).getChild(0).getChild(0).getText() + "." + astmp.getChild(0).getChild(1).getText()); 137 | } 138 | } 139 | break; 140 | } 141 | } 142 | 143 | /** 144 | * from部分分析 145 | * 1. TOK_TABREF 表 146 | * 2. *_JOIN 各种join 147 | * 3. subQuery:子查询 148 | * @param qf 149 | */ 150 | private static void fromAnalysis(ASTNode qf) { 151 | // TODO Auto-generated method stub 152 | 153 | int cc = 0; 154 | int cp = 0; 155 | 156 | switch (qf.getToken().getType()) { 157 | case HiveParser.TOK_TABREF: 158 | ASTNode atmp = (ASTNode)qf.getChild(0); 159 | String tb = atmp.getChildCount()==1 ? atmp.getChild(0).toString() : atmp.getChild(0).toString() + "." + atmp.getChild(1).toString() ; 160 | String res = qf.getChildCount()==1 ? 161 | tb : tb + "\talias : \t" + qf.getChild(1).toString(); 162 | System.out.println("* From Table :\t" + res); 163 | 164 | break; 165 | case HiveParser.TOK_LEFTOUTERJOIN: 166 | cc = qf.getChildCount(); 167 | 168 | for ( cp = 0; cp < cc; cp++) { 169 | ASTNode atm = (ASTNode)qf.getChild(cp); 170 | fromAnalysis(atm); 171 | } 172 | break; 173 | case HiveParser.TOK_JOIN: 174 | cc = qf.getChildCount(); 175 | 176 | for ( cp = 0; cp < cc; cp++) { 177 | ASTNode atm = (ASTNode)qf.getChild(cp); 178 | fromAnalysis(atm); 179 | } 180 | break; 181 | case HiveParser.TOK_SUBQUERY: // 子查询 182 | // 看count, 183 | // 只要子查询,count=2, 一个子查询[可能为嵌套],一个为别名 184 | //分析第一个: 185 | //书写形式有:1. TOK_QUERY 2. TOK_UNION 3.TOK_JOIN 186 | // SubParseQuery(ASTNodeParseQuery,ASTNodetmp03); 187 | subQueryAnalysis((ASTNode)qf.getChild(0)); 188 | break; 189 | case HiveParser.TOK_LATERAL_VIEW: 190 | cc = qf.getChildCount(); 191 | for ( cp = 0; cp < cc; ++cp) { 192 | fromAnalysis((ASTNode)qf.getChild(cp)); 193 | } 194 | break; 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /SqlExplainByDruid.java: -------------------------------------------------------------------------------- 1 | package com.jd.sql.p; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import com.alibaba.druid.sql.SQLUtils; 9 | import com.alibaba.druid.sql.ast.SQLExpr; 10 | import com.alibaba.druid.sql.ast.SQLStatement; 11 | import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; 12 | import com.alibaba.druid.sql.ast.expr.SQLCaseExpr; 13 | import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; 14 | import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; 15 | import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; 16 | import com.alibaba.druid.sql.ast.statement.SQLSelect; 17 | import com.alibaba.druid.sql.ast.statement.SQLSelectItem; 18 | import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; 19 | import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; 20 | import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; 21 | import com.alibaba.druid.sql.ast.statement.SQLTableSource; 22 | import com.alibaba.druid.sql.parser.SQLParserUtils; 23 | import com.alibaba.druid.sql.parser.SQLStatementParser; 24 | import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; 25 | import com.alibaba.druid.util.JdbcUtils; 26 | 27 | /** 28 | * 29 | * 借助阿里开源的druid项目代码 30 | * SQL 执行分解动作.... 31 | * 1. 不支持的操作:lateral VIEW 32 | * 2. 不支持insert xxxx select * 33 | * 3. 不支持create xxxx select * 34 | * 4. 偶尔bui支持case函数,待测试 35 | * 5. 只支持查询语句 SQLSelectStatement 36 | * TODO: 2、3特殊处理下 SUCC 37 | * @author zhangkai3 38 | * 39 | */ 40 | public class SqlExplain { 41 | 42 | public static String pPrefix = null; 43 | 44 | public static void main(String[] args) throws InterruptedException { 45 | //yes String sql = " SELECT CASE WHEN m.cata_id IS NULL THEN n.cata_id ELSE m.cata_id END AS cata_id, n.att_id, n.att_name, b.value_id, b.value_name, n.type FROM (SELECT att_id,att_name,cata_id,group_id,type FROM fdm.fdm_forest_attribute_chain WHERE dp='ACTIVE') n LEFT OUTER JOIN (SELECT cata_id,group_id ,type FROM fdm.fdm_forest_attribute_group_chain WHERE dp='ACTIVE') m ON n.group_id=m.group_id AND n.type=m.type LEFT OUTER JOIN (SELECT att_id,value_id, value_name,type FROM fdm.fdm_forest_attribute_value_chain WHERE dp='ACTIVE') b ON n.att_id=b.att_id AND n.type=b.type where a=1; "; 46 | // no String sql = "select * from ( select county.county_id as dim_county_id, county.county_name as dim_county_name, county.county_id as county_id, city.city_id as dim_city_id, city.city_name as dim_city_name, city.city_id as city_id, province.province_id as dim_province_id, province.province_name as dim_province_name, province.province_id as province_id, case when province.province_id in (2,12,14,15) then '3' when province.province_id in (4,22,24,25,26) then '4' when province.province_id in (1,12,6,3,13,5,11) then '6' when province.province_id in (23,16,19,20) then '10' when province.province_id in (17,18,7,21) then '600' when province.province_id in (8,9,10) then '611' when province.province_id in (27,28,29,30,31) then '645' end as dim_subd_num, case when province.province_id in (2,12,14,15) then '上海分公司' when province.province_id in (4,22,24,25,26) then '成都分公司' when province.province_id in (1,12,6,3,13,5,11) then '北京分公司' when province.province_id in (23,16,19,20) then '广州分公司' when province.province_id in (17,18,7,21) then '武汉分公司' when province.province_id in (8,9,10) then '沈阳分公司' when province.province_id in (27,28,29,30,31) then '西安分公司' end as dim_subd_name, case when province.province_id in (2,12,14,15) then '3' when province.province_id in (4,22,24,25,26) then '4' when province.province_id in (1,12,6,3,13,5,11) then '6' when province.province_id in (23,16,19,20) then '10' when province.province_id in (17,18,7,21) then '600' when province.province_id in (8,9,10) then '611' when province.province_id in (27,28,29,30,31) then '645' end as subd_num, '' as sort_num from (select loc_id as city_id, loc_name as city_name, super_loc_id as province_id from tmp.tmp_assort where loc_type = 'city' ) city left outer join (select loc_id as county_id, loc_name as county_name, super_loc_id as city_id from tmp.tmp_assort) county on city.city_id = county.city_id left outer join ( select loc_id as province_id , loc_name as province_name from tmp.tmp_assort) province on city.province_id = province.province_id where coalesce(county.county_id,'') <> '' ) q"; 47 | String sql = "SeLECT d.shop_id, s.ads, s.edm, s.unions FROM ( select pop_id, max(case when privilige_code='ads:login' then 'login' END) as ads, max(case when privilige_code='edm:login' then 'login' END) as edm, max(case when privilige_code='union:login' then 'login' END) as unions from bdm.bdm_mmp_mk_pop_privilige_da where dt=' + ht.data_day_str + ' group by pop_id) S join (select id,shop_id from fdm.fdm_pop_vender_vender_chain where start_date <=' + ht.data_day_str + ' and end_date > ' + ht.data_day_str + ' group by id,shop_id) d on s.pop_id=d.id"; 48 | // yes String sql = "select dim_item_fin_third_cate_id as mapping_id, map( 'dim_item_fin_first_cate_name',dim_item_fin_zero_cate_name ) from dim.dim_item_fin_cate_getmap"; 49 | // yes String sql = "select item_third_cate_cd as mapping_id, map( 'item_first_cate_cd', item_first_cate_cd ,'item_first_cate_name',item_first_cate_name ,'item_second_cate_cd' ,item_second_cate_cd ,'item_second_cate_name',item_second_cate_name ,'item_third_cate_cd' ,item_third_cate_cd ,'item_third_cate_name',item_third_cate_name ) from dim.dim_sku_category"; 50 | // String sql = "select cast(a.dim_store_num as string) as dim_store_num, concat(regexp_replace(b.delv_center_name,'配送中心',''),a.store_name) as dim_store_name, cast(a.int_org_num as string) as store_id, cast(a.wh_cate_desc as string ) as wh_cate_desc, cast(b.subd_num as string) as dim_subd_num, cast(c.dim_subd_name as string) as dim_subd_name, cast(b.subd_num as string) as subd_num, cast(a.delv_center_num as string) as dim_delv_center_num, cast(b.delv_center_name as string) as dim_delv_center_name, cast(a.delv_center_num as string) as delv_center_num, null as sort_num, cast(c.region_name as string) as region_name, cast(a.settle_org_num as string) as settle_org_num, cast(a.settle_org_name as string) as settle_org_name from ( select concat(rpad(delv_center_num,4,'0'),lpad(int_org_num,4,'0')) as dim_store_num, store_name, int_org_num, wh_cate_desc, delv_center_num, case when int_org_num=5 and delv_center_num=6 then '620' when int_org_num=5 and delv_center_num=3 then '624' when int_org_num=5 and delv_center_num=10 then '623' when int_org_num=5 and delv_center_num=4 then '613' when int_org_num=5 and delv_center_num=5 then '622' when int_org_num=5 and delv_center_num=9 then '621' else subd_num end as settle_org_num, case when int_org_num=5 and delv_center_num=6 then '图书运营北京分公司' when int_org_num=5 and delv_center_num=3 then '图书运营上海分公司' when int_org_num=5 and delv_center_num=10 then '图书运营广州分公司' when int_org_num=5 and delv_center_num=4 then '图书运营成都分公司' when int_org_num=5 and delv_center_num=5 then '图书运营武汉分公司' when int_org_num=5 and delv_center_num=9 then '图书运营沈阳分公司' else subd_name end as settle_org_name from ( select stores.int_org_num, stores.store_name, stores.delv_center_num, stores.src_sys_cd, stores.wh_cate_desc, stores.wms_wh_cd, stores.wms_wh_name, stores.wms_wh_type, stores.store_addr, stores.store_contact, stores.store_tel, stores.store_mobile_no, stores.wms_ver, stores.subd_num, stores.subd_name, stores.region_name, store_maint.wms2_store_id, delv_center.delv_center_brevity_cd from ( select storeid as int_org_num, storename as store_name, delivercentercode as delv_center_num, null as src_sys_cd, storetype as wh_cate_desc, wareno as wms_wh_cd, warename as wms_wh_name, locno as wms_wh_type, addr as store_addr, contact as store_contact, tel as store_tel, mobile as store_mobile_no, wmsversion as wms_ver, cast(mcustno as string) as subd_num, mcustname as subd_name, area as region_name, mcustno from fdm.fdm_erp_wareinfo_chain where start_date <= ' + ht.date_today + ' and end_date > ' + ht.date_tomorrow + ' ) stores left outer join ( select int_org_num, wms2_store_id, delv_center_num from tmp.tmp_d02_store_maint ) store_maint on stores.int_org_num= store_maint.int_org_num and stores.delv_center_num= store_maint.delv_center_num left outer join ( select delv_center_brevity_cd ,delv_center_num from dim.dim_d99_delv_center_brevity_cd ) delv_center on delv_center.delv_center_num= stores.delv_center_num ) tmp_d02_store )a join ( select subd_num, dim_delv_center_name as delv_center_name, delv_center_num from dim.dim_delv_center ) b on a.delv_center_num=b.delv_center_num join ( select dim_subd_name, subd_num, Region_Name from dim.dim_subd ) c on b.subd_num=c.subd_num"; 51 | //String sql = "select ' + ht.data_day_str + ' as stat_date ,sku.item_sku_id as item_sku_id ,sku.item_name as item_name ,sku.item_id as item_id ,sku.brandname as product_name ,sku.item_first_cate_cd as item_first_cate_cd ,sku.item_first_cate_name as item_first_cate_name ,sku.item_second_cate_cd as item_second_cate_cd ,sku.item_second_cate_name as item_second_cate_name ,sku.item_third_cate_cd as item_third_cate_cd ,sku.item_third_cate_name as item_third_cate_name ,sku.item_status_cd as item_status_cd ,sku.pur_dist_flag as pur_dist_flag ,sku.pop_coop_mode_cd as pop_coop_mode_cd ,sku.pop_vender_id as pop_vender_id ,sku.pop_vender_name as pop_vender_name ,sku.pop_vender_status_cd as pop_vender_status_cd ,sku.pop_vender_status_name as pop_vender_status_name ,sku.shop_id as shop_id ,sku.shop_name as shop_name ,sku.major_supp_brevity_code as major_supp_brevity_code ,sku.purchaser_num as purchaser_num ,sku.purchaser_name as purchaser_name ,sku.len as len ,sku.width as width ,sku.height as height ,sku.calc_volume as calc_volume ,sku.size as size ,sku.wt as wt ,sku.pop_flag as pop_flag ,sku.valid_flag as valid_flag ,sku.support_cash_on_deliver_flag as support_cash_on_deliver_flag ,orders.new_order_quantity as new_order_quantity ,orders.new_order_amount as new_order_amount ,orders1.cancel_order_quantity as cancel_order_quantity ,orders1.cancel_order_amount as cancel_order_amount ,orders1.cancel_order_user_quantity as cancel_order_user_quantity ,orders2.finished_order_quantity as finished_order_quantity ,orders2.finished_order_amount as finished_order_amount ,repair_new.quantity as repair_new_quantity ,repair_new.amount as repair_new_amount ,repair_received.repair_received_quantity as repair_received_quantity ,repair_received.repair_received_amount as repair_received_amount ,repair_paid.repair_paid_quantity as repair_paid_quantity ,repair_paid.repair_paid_amount as repair_paid_amount ,0 as page_view_quantity ,0 as view_user_quantity ,score.score_1_quantity as score_1_quantity ,score.score_2_quantity as score_2_quantity ,score.score_3_quantity as score_3_quantity ,score.score_4_quantity as score_4_quantity ,score.score_5_quantity as score_5_quantity ,core_stock.numk as numk ,sw1.zixun as zixun ,sw1.huizixun as huizixun from ( select item_sku_id ,item_name ,item_id ,brandname ,item_first_cate_cd ,item_first_cate_name ,item_second_cate_cd ,item_second_cate_name ,item_third_cate_cd ,item_third_cate_name ,item_status_cd ,pur_dist_flag ,pop_coop_mode_cd ,pop_vender_id ,pop_vender_name ,pop_vender_status_cd ,pop_vender_status_name ,shop_id ,shop_name ,major_supp_brevity_code ,purchaser_num ,purchaser_name ,len ,width ,height ,calc_volume ,size ,wt ,pop_flag ,valid_flag ,support_cash_on_deliver_flag from gdm.gdm_sku_basic_attrib_da where dt=' +ht.data_day_str+ ' )sku left outer join ( select item_sku_id ,count(distinct sale_ord_id) as new_order_quantity ,sum(after_prefr_amount) as new_order_amount from gdm_m04_ord_det_sum where to_date(sale_ord_tm)=' + ht.data_day_str + ' group by item_sku_id )orders on sku.item_sku_id=orders.item_sku_id left outer join ( select item_sku_id ,count(distinct sale_ord_id) as cancel_order_quantity ,sum(after_prefr_amount) as cancel_order_amount ,count(distinct user_log_acct) as cancel_order_user_quantity from gdm_m04_ord_det_sum where to_date(ord_cancel_tm)=' + ht.data_day_str + ' group by item_sku_id )orders1 on sku.item_sku_id=orders1.item_sku_id left outer join ( select item_sku_id ,count(distinct sale_ord_id) as finished_order_quantity ,sum(after_prefr_amount) as finished_order_amount from gdm_m04_ord_det_sum where to_date(Ord_Complete_Tm)=' + ht.data_day_str + ' and sale_ord_valid_flag=1 group by item_sku_id )orders2 on sku.item_sku_id=orders.item_sku_id left outer join ( select ware_id as sku_id, count(afs_service_detail_id) as quantity, sum(pay_price) as amount from fdm.fdm_afs_afs_service_detail_chain where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + ' and ware_type=10 group by ware_id ) repair_new on sku.item_sku_id=repair_new.sku_id left outer join ( select T1.ware_id as sku_id, count(distinct T1.afs_service_id) as repair_received_quantity, sum(T2.cost_price) as repair_received_amount from (select * from fdm.fdm_afs_afs_service_detail_chain where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + ' and ware_type=10) T1 join (select * from fdm.fdm_afs_part_receive_chain where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + 'and to_date(afs_apply_time)=' + ht.data_day_str + ') T2 on T1.afs_service_id=T2.afs_service_id group by T1.ware_id )repair_received on sku.item_sku_id = repair_received.sku_id left outer join ( select T1.ware_id as sku_id, count(distinct T1.afs_service_id) as repair_paid_quantity, sum(T2.suggest_amount) as repair_paid_amount from (select * from fdm.fdm_afs_afs_service_chain where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + ' and approve_result=21 ) T1 join (select * from fdm.fdm_afs_afs_refund_chain where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + ' and to_date(create_date)=' + ht.data_day_str + ' ) T2 on T1.afs_service_id=T2.afs_service_id group by T1.ware_id )repair_paid on sku.item_sku_id = repair_received.sku_id left outer join ( select referenceid as sku_id, sum( case when score = 1 then 1 else 0 end ) as score_1_quantity, sum( case when score = 2 then 1 else 0 end ) as score_2_quantity, sum( case when score = 3 then 1 else 0 end ) as score_3_quantity, sum( case when score = 4 then 1 else 0 end ) as score_4_quantity, sum( case when score = 5 then 1 else 0 end ) as score_5_quantity from fdm.fdm_club_comment_chain where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + ' and to_date(creationtime) = ' + ht.data_day_str + ' group by referenceid ) score on sku.item_sku_id=score.sku_id left outer join ( select wid ,sum( numrk - numck) as numk from fdm.fdm_pek_core_stockstatday where dt = ' + ht.data_day_str + ' group by wid )core_stock on sku.item_sku_id=core_stock.wid left outer join ( SELECT sw.wid ,sum(case when sw.sfid=0 then 1 else 0 end ) AS zixun ,sum(case when sw.sfid !=1 then 1 else 0 end ) AS huizixun FROM fdm.fdm_club_sayword_chain sw where start_date <=' + ht.data_day_str + ' and end_date >' + ht.data_day_str + ' and sw.syn=1 and to_date(sw.ordertime) = ' + ht.data_day_str + ' group by sw.wid )sw1 on sku.item_sku_id=sw1.wid "; 52 | //String sql = "SELECT CASE WHEN m.cata_id IS NULL THEN n.cata_id ELSE m.cata_id END AS cata_id, n.att_id, n.att_name, b.value_id, b.value_name, n.type FROM (SELECT att_id,att_name,cata_id,group_id,type FROM fdm.fdm_forest_attribute_chain WHERE dp='ACTIVE') n LEFT OUTER JOIN (SELECT cata_id,group_id ,type FROM fdm.fdm_forest_attribute_group_chain WHERE dp='ACTIVE') m ON n.group_id=m.group_id AND n.type=m.type LEFT OUTER JOIN (SELECT att_id,value_id, value_name,type FROM fdm.fdm_forest_attribute_value_chain WHERE dp='ACTIVE') b ON n.att_id=b.att_id AND n.type=b.type; "; 53 | //String sql = "SELECT n.cata_id, n.att_id, n.att_name, n.value_id, n.value_name, SUM(d.pay_amount) as pays, COUNT(DISTINCT d.user_id) as uids, COUNT(DISTINCT e.shop_id) as shops, COUNT(DISTINCT s.product_sku_id) as sks FROM (SELECT * FROM dim.dim_odp_ind_prd_attr) n LEFT OUTER JOIN (SELECT product_sku_id,prop_type, CASE WHEN prop_type=3 THEN SPLIT(atts,':') ELSE SPLIT(atts,':') END AS value_id FROM fdm.fdm_product_pop_property_chain WHERE dp='ACTIVE' ) s ON n.att_id=s.att_id AND n.value_id=s.value_id AND s.prop_type=n.type LEFT OUTER JOIN (SELECT DISTINCT item_id,shop_id FROM gdm.gdm_m03_item_sku_da WHERE dt='2014-08-10' ) e ON s.product_sku_id=e.item_id JOIN (SELECT item_id, sale_qtty, after_prefr_amount + sku_freight_amount AS pay_amount, user_log_acct AS user_id FROM adm.adm_s14_ol_shop_orders_det WHERE dt = '2014-08-10' AND is_deal_ord = 1 AND item_id IS NOT NULL ) d ON s.product_sku_id = d.item_id WHERE n.value_name!='品牌' AND n.att_name!='品牌' GROUP BY n.cata_id, n.att_id, n.att_name, n.value_id, n.value_name; "; 54 | // String sql = "create table xxx select * from tmp.xxxsdfs abc"; 55 | // sql = "insert overwrite table dim.dim_odp_ind_prd_attr partition (dt='2014-07-01') select * from tmp.xxxsdfs abc"; 56 | sql = "USE tmp;CREATE TABLE tmp_odp_ind_prd_attr_abc AS select * from tmp.xxxsdfs abc"; 57 | if(sql.toLowerCase().indexOf("create")>-1 || sql.toLowerCase().indexOf("insert") > -1) { 58 | sql = sql.substring(sql.toLowerCase().indexOf("select")); 59 | sqlDecomposition(sql, true); 60 | } else { 61 | sqlDecomposition(sql); 62 | } 63 | } 64 | /** 65 | * 66 | * @param query 67 | * @param isPrefix 68 | * @throws InterruptedException 69 | */ 70 | public static void sqlDecomposition(String query, boolean isPrefix) throws InterruptedException { 71 | 72 | Map apMap = new HashMap(); 73 | StringBuffer from = new StringBuffer(); 74 | // parser得到AST 75 | SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(query, JdbcUtils.HIVE); 76 | List stmtList = parser.parseStatementList(); 77 | // 将AST通过visitor输出 78 | SQLASTOutputVisitor visitor = SQLUtils.createFormatOutputVisitor(from, stmtList, JdbcUtils.HIVE); 79 | List sL = new ArrayList(); 80 | SQLStatement stmt = stmtList.iterator().next(); 81 | // if(stmt instanceof SQLSelectStatement){ 82 | SQLSelectStatement sstmt = (SQLSelectStatement) stmt; 83 | SQLSelect sqlselect = sstmt.getSelect(); 84 | SQLSelectQueryBlock sqb = (SQLSelectQueryBlock) sqlselect.getQuery(); 85 | SQLTableSource fromx = sqb.getFrom(); 86 | fromx.accept(visitor); 87 | //query.getWhere().accept(whereVisitor); 88 | sL = sqb.getSelectList(); 89 | // } 90 | StringBuffer sb = new StringBuffer(); 91 | for (SQLSelectItem sqi : sL) { 92 | if (sqi.getExpr() instanceof SQLCaseExpr) { 93 | sb.append(sqi.getAlias()).append(","); 94 | } else { 95 | sb.append(sqi.toString()).append(","); 96 | } 97 | 98 | } 99 | Thread.sleep(500); 100 | System.out.println("*****************分析结果*********************************"); 101 | Thread.sleep(500); 102 | System.out.println("* 结果列表 : " 103 | + sb.toString().substring(0, sb.toString().length() - 1)); 104 | Thread.sleep(500); 105 | System.out.println("*\n*****************来源列表*********************************"); 106 | sourceAnalysis(fromx, apMap); 107 | Thread.sleep(500); 108 | System.out.println("*****************分析结束*********************************"); 109 | 110 | } 111 | 112 | /** 113 | * SQL分解动作 114 | * @param query 115 | * @throws InterruptedException 116 | */ 117 | public static void sqlDecomposition(String query) throws InterruptedException { 118 | sqlDecomposition(query, false); 119 | } 120 | 121 | public static void sourceAnalysis(SQLTableSource from, 122 | Map apMap) { 123 | if (from instanceof SQLExprTableSource) { 124 | System.out.println("真实表名: "+from.toString()); 125 | } else if (from instanceof SQLJoinTableSource) { 126 | SQLTableSource left = ((SQLJoinTableSource) from).getLeft(); 127 | SQLTableSource right = ((SQLJoinTableSource) from).getRight(); 128 | if (left.getAlias() != null) 129 | print(left); 130 | print(right); 131 | sourceAnalysis(left, apMap); 132 | sourceAnalysis(right, apMap); 133 | } else if (from instanceof SQLSubqueryTableSource) { 134 | 135 | } 136 | } 137 | 138 | public static void JudgeExpc() { 139 | 140 | } 141 | 142 | public static void print(SQLTableSource sql) { 143 | String tableName = ((SQLSelectQueryBlock) ((SQLSubqueryTableSource) sql) 144 | .getSelect().getQuery()).getFrom().toString(); 145 | List itemList = ((SQLSelectQueryBlock) ((SQLSubqueryTableSource) sql) 146 | .getSelect().getQuery()) 147 | .getSelectList(); 148 | StringBuffer sb = new StringBuffer(); 149 | SQLExpr sqlExpr = null; 150 | for (SQLSelectItem item : itemList) { 151 | // SQLAggregateExpr.class 152 | // SQLAllColumnExpr.class 153 | // SQLAllExpr.class 154 | // SQLAnyExpr.class 155 | // SQLBetweenExpr.class 156 | // SQLBinaryOperator.class 157 | // SQLBinaryOpExpr.class 158 | // SQLBooleanExpr.class 159 | // SQLCaseExpr.class 160 | // SQLCastExpr.class 161 | // SQLCharExpr.class 162 | // SQLCurrentOfCursorExpr.class 163 | // SQLDefaultExpr.class 164 | // SQLExistsExpr.class 165 | // SQLHexExpr.class 166 | // SQLIdentifierExpr.class 167 | // SQLInListExpr.class 168 | // SQLInSubQueryExpr.class 169 | // SQLIntegerExpr.class 170 | // SQLListExpr.class 171 | // SQLLiteralExpr.class 172 | // SQLMethodInvokeExpr.class 173 | // SQLNCharExpr.class 174 | // SQLNotExpr.class 175 | // SQLNullExpr.class 176 | // SQLNumberExpr.class 177 | // SQLNumericLiteralExpr.class 178 | // SQLPropertyExpr.class 179 | // SQLQueryExpr.class 180 | // SQLSomeExpr.class 181 | // SQLTextLiteralExpr.class 182 | // SQLUnaryExpr.class 183 | // SQLUnaryOperator.class 184 | // SQLVariantRefExpr.class ................... 185 | sqlExpr = item.getExpr(); 186 | if(sqlExpr instanceof SQLAggregateExpr) { 187 | } else if (sqlExpr instanceof SQLIdentifierExpr) { 188 | sb.append(((SQLIdentifierExpr)sqlExpr).getName()).append(","); 189 | } 190 | sb.append(item.getAlias()).append(","); 191 | } 192 | try { 193 | Thread.sleep(500); 194 | } catch (InterruptedException e) { 195 | // TODO Auto-generated catch block 196 | e.printStackTrace(); 197 | } 198 | System.out 199 | .println("* 真实表名: " + tableName + "\t別名:" 200 | + sql.getAlias() 201 | + "\n* 获取列:\t" 202 | + itemList.toString()); 203 | } 204 | public static String getpPrefix() { 205 | return pPrefix; 206 | } 207 | public static void setpPrefix(String pPrefix) { 208 | SqlExplain.pPrefix = pPrefix; 209 | } 210 | } 211 | 212 | 213 | class AnalysisPool { 214 | private String select; 215 | private int sort; // 排序 216 | private String parent; 217 | public String getSelect() { 218 | return select; 219 | } 220 | public void setSelect(String select) { 221 | this.select = select; 222 | } 223 | public int getSort() { 224 | return sort; 225 | } 226 | public void setSort(int sort) { 227 | this.sort = sort; 228 | } 229 | public String getParent() { 230 | return parent; 231 | } 232 | public void setParent(String parent) { 233 | this.parent = parent; 234 | } 235 | 236 | } 237 | --------------------------------------------------------------------------------