打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Mysql Oracle按组合并,行列转换SQL
userphoto

2015.10.18

关注


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




本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
使用 case when进行行列转换
SQL 行转列,列转行
Panadas 中利用DataFrame对象的.loc[,]、.iloc[,]方法抽取数据
sql如何行转列,列转行
行列转换 交叉表
交叉表、行列转换和交叉查询经典
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服