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




转载于:https://my.oschina.net/laigous/blog/210321

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值