Mysql Oracle按组合并,行列转换SQL


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 
		 */
	}
}




你可能感兴趣的:(Mysql Oracle按组合并,行列转换SQL)