public class SqlUtil { /** * 按组分类再拼接同类后行列转换sql <br/> * CREATE TABLE TEST_TABLE <br/> * ID NUMBER PK <br/> * NAME VARCHAR 姓名(FK) <br/> * TYPE VARCHAR 科目 <br/> * VALUE NUMBER 分数 <br/> * TERM VARCHAR 学期 <br/> * ID NAME TYPE VALUE TERM <br/> * 1 小明(001) 英语 90 2010 <br/> * 2 小明(001) 英语 89 2011 <br/> * 3 小明 (001) 数学 50 2010 <br/> * 4 小明 (001) 数学 81 2011 <br/> * 5 小明 (001) 语文 78 2010 <br/> * 6 小张(002) 数学 89 2010 <br/> * 7 小张(002) 数学 90 2010 <br/> * 8 小张 (002) 英语 59 2010 <br/> * 9 小张 (002) 语文 99 2011 <br/> * 希望得到所有学生各学期的成绩 <br/> * classifyMap = {"英语=E","数学=M","语文=C"} <br/> * classifyBaseGroupSql("TYPE",classifyMap,"NAME",",","TEST_TABLE","VALUE","VALUE>80") <br/> * return <br/> * E M C NAME <br/> * 90,89 81 小明(001) <br/> * 89,90 99 小张(002) <br/> * 适用于单表根据字段分组后有多种类型的数据并且该类型有多条记录, * 而又希望分组后只产生一条数据 * @param classifyColums (not-null) * 分类的字段,必须为tabel的字段 * @param classifyMap (not-null) * 分类的数组Map值,key:classifyColums的值,value:得到的列名 * @param classifyGroup (not-null) * 分类的组,必须为tabel的字段 * @param groupSeparate (not-null) * info以classifyGroup分组的分隔符 * @param tabel (not-null) * 数据库表名 不能为空 * @param info (not-null) * 需要的信息 为tabel表字段或字段拼接 * @param condition * 得到信息的条件如果没有则为null,必须为tabel的字段 * @return sql字符串 */ public static String classifyBaseGroupSql(String classifyColums,Map<String,String> classifyMap,String classifyGroup, String groupSeparate,String tabel,String info,String condition){ if(CommUtils.isNull(classifyGroup) || CommUtils.isNull(info)||CommUtils.isNull(groupSeparate) || CommUtils.isNull(tabel) || CommUtils.isNull(classifyColums) ||classifyMap==null||classifyMap.size()==0){ throw new NullPointerException(); } if(StringUtils.isBlank(condition)){ condition = " 1=1"; } StringBuffer sql = new StringBuffer("SELECT "); /** oracle版 //行列转换 for(String type:classifyMap.keySet()){ sql.append(" max(decode("+classifyColums+", '"+type+"', str)) "+classifyMap.get(type)+","); } sql.append(" max(decode("+classifyGroup+", "+classifyGroup+", "+classifyGroup+")) "+classifyGroup //按info值拼接 +" from (select "+classifyGroup+","+classifyColums+",ltrim(max(sys_connect_by_path(val, '"+groupSeparate+"'))) str" + //所有数据分行 " from (select "+classifyGroup+","+classifyColums+",val," + " row_number() over(partition by "+classifyColums+", "+classifyGroup+" order by val) n" + //得到符合条件的所有数据 " from (select "+classifyGroup+","+classifyColums+",("+info+") val" + " from "+tabel+" where "+condition+"))t"+ " start with n = 1 connect by n = prior n + 1" +//拼接条件 " and "+classifyColums+" = prior "+classifyColums+" and "+classifyGroup+" = prior "+classifyGroup+ " group by "+classifyColums+", "+classifyGroup+")" + " group by "+classifyGroup);**/ //mysql版 //行列转换 for(String type:classifyMap.keySet()){ sql.append(" MAX(IF("+classifyColums+"='"+type+"', str,'')) "+classifyMap.get(type)+","); } sql.append("MAX(IF("+classifyGroup+"="+classifyGroup+","+classifyGroup+",''))"+classifyGroup+ //按info值拼接 " FROM ( SELECT "+classifyGroup+","+classifyColums+",GROUP_CONCAT(val SEPARATOR '"+groupSeparate+"')str "+ " FROM (SELECT "+classifyGroup+","+classifyColums+",("+info+") val" + " FROM "+tabel+" WHERE "+condition+")t" + " GROUP BY "+classifyColums+", "+classifyGroup+")t" + " group by "+classifyGroup); return sql.toString(); } /** * 按组分类后行列转换sql 例: <br/> * CREATE TABLE TEST_TABLE <br/> * ID NUMBER PK <br/> * NAME VARCHAR 姓名(FK) <br/> * TYPE VARCHAR 科目 <br/> * VALUE NUMBER 分数 <br/> * ID NAME TYPE VALUE <br/> * 1 小明(001) 英语 90 <br/> * 2 小明 (001) 数学 50 <br/> * 3 小明 (001) 语文 78 <br/> * 4 小张(002) 数学 89 <br/> * 5 小张 (002) 英语 59 <br/> * 6 小张 (002) 语文 99 <br/> * classifyMap = {"英语=E","数学=M","语文=C"} <br/> * changeLineToRowSql("TYPE",classifyMap,"NAME","TEST_TABLE","VALUE","VALUE>80") <br/> * return <br/> * E M C NAME <br/> * 90 小明(001)<br/> * 89 99 小张(002)<br/> * 适用于单表根据字段分组后有多种类型的数据并且该类型只有一条记录, * 而又希望分组后只产生一条数据 * @param classifyColums (not-null) * 分类的字段,必须为tabel的字段 * @param classifyMap (not-null) * 分类的数组Map值,key:classifyColums的值,value:得到的列名 * @param classifyGroup (not-null) * 分类的组,必须为tabel的字段 * @param tabel (not-null) * 数据库表名 * @param info (not-null) * 需要的信息 为tabel表字段或字段拼接 * @param condition * 得到信息的条件如果没有则为null,必须为tabel的字段 * @return sql字符串 */ public static String changeLineToRowSql(String classifyColums,Map<String,String> classifyMap,String classifyGroup ,String tabel,String info,String condition){ if(CommUtils.isNull(classifyGroup) || CommUtils.isNull(info) || CommUtils.isNull(tabel) || CommUtils.isNull(classifyColums) ||classifyMap==null||classifyMap.size()==0){ throw new NullPointerException(); } if(StringUtils.isBlank(condition)){ condition = " 1=1"; } StringBuffer sql = new StringBuffer("SELECT "); /**oracle版 for(String type:classifyMap.keySet()){ sql.append(" max(decode("+classifyColums+", '"+type+"', val)) "+classifyMap.get(type)+","); } sql.append(" max(decode("+classifyGroup+", "+classifyGroup+", "+classifyGroup+")) "+classifyGroup +" from (select "+classifyGroup+","+classifyColums+",("+info+") val" + " from "+tabel+" where "+condition+")" + " group by "+classifyGroup);**/ //mysql版 for(String type:classifyMap.keySet()){ sql.append(" MAX(IF("+classifyColums+"='"+type+"', val,'')) "+classifyMap.get(type)+","); } sql.append("MAX(IF("+classifyGroup+"="+classifyGroup+","+classifyGroup+",''))"+classifyGroup+ " FROM (SELECT "+classifyGroup+","+classifyColums+",("+info+") val" + " FROM "+tabel+" WHERE "+condition+")t" + " GROUP BY "+classifyGroup); return sql.toString(); } /** * 按组合并 * (只针对单表 进行多个单表字段数据合并) * @EX groupLinkValue("name",",","TEST_TABLE","type || ':' || value"," value > 80 and value < 100 ") * @param classifyGroup (not-null) * 分类的组 (PK,唯一 ,关联表字段) * @param groupSeparate (not-null) * 多行数据合并分隔符 * @param tabel (not-null) * 数据库表名 * @param info (not-null) * 合并的数据,(单表字段or单表多字段)返回字段别名为val * @param condition SQL条件语句 * 多个条件用 and 连接 * @return 返回NULL 表示参数异常 * @author CHENJIANIAN * @data 2013-5-22 */ public static String groupLinkValue(String classifyGroup, String groupSeparate,String tabel,String info,String condition){ if(CommUtils.isNull(classifyGroup) || CommUtils.isNull(info) || CommUtils.isNull(tabel) || CommUtils.isNull(groupSeparate)){ return null; } if(StringUtils.isBlank(condition)){ condition = " 1=1"; } StringBuffer sql = new StringBuffer(); /**oracle版 sql.append(" select "+classifyGroup+",max(sys_connect_by_path(val, '"+groupSeparate+"')) val" + //所有数据分行 " from (select "+classifyGroup+",val," + " row_number() over(partition by "+classifyGroup+" order by val) n" + //得到符合条件的所有数据 " from (select "+classifyGroup+",("+info+") val" + " from "+tabel+" where "+condition+"))t"+ " start with n = 1 connect by n = prior n + 1" +//拼接条件 " and "+classifyGroup+" = prior "+classifyGroup+ " group by "+classifyGroup);**/ //mysql版 sql.append("SELECT "+classifyGroup+",GROUP_CONCAT("+info+" SEPARATOR '"+groupSeparate+"') val " + " FROM "+tabel+" WHERE "+condition+ " GROUP BY "+classifyGroup); return sql.toString(); } public static void main(String args[]){ Map<String,String> map = new HashMap<String, String>(); map.put("1", "in_ip"); map.put("2", "ip"); map.put("3", "control_ip"); System.out.println(SqlUtil.changeLineToRowSql("ip_type", map, "server_id", "host_server_ip", "ip", "1=1 order by ip_type")); System.out.println(SqlUtil.groupLinkValue("server_id", ",", "host_server_ip", "ip", "1=1 order by ip_type")); /* * CREATE TABLE TEST_TABLE * ID NUMBER PK * NAME VARCHAR 姓名(FK) * TYPE VARCHAR 科目 * VALUE NUMBER 分数 * * 1 小明(001) 英语 90 * 2 小明 (001) 数学 50 * 3 小明 (001) 语文 78 * 4 小张(002) 数学 89 * 5 小张 (002) 英语 59 * 6 小张 (002) 语文 99 * * */ groupLinkValue("name",",","TEST_TABLE","type || ':' || value"," value < 60 "); /* RETURN * 小明 ,数学:50 * 小张 ,英语:59 */ groupLinkValue("name",",","TEST_TABLE","type || ':' || value"," value > 80 and value < 100 "); /* RETURN * 小明 ,英语:90 * 小张 ,数学:89,语文:99 */ } }