• Post author:
  • Post category:数据库
  • Post comments:0评论
  • Reading time:1 mins read

最近写了个特别复杂的业务,涉及到一个比较难写的Sql语句,在行转列的基础上需要多表动态联查,也就是说,查询结果的列数是可变的,数量根据联查的表的行数来决定,先贴出语句:

CREATE DEFINER=`root`@`%` PROCEDURE `sp_getpointlist`(projectType INT)
BEGIN
	SET @ProjectType = projectType;
	SET @SQL = NULL;
		SELECT
			GROUP_CONCAT( DISTINCT CONCAT( 'Max(IF(s.RuleId = ''', r.Id, ''', s.`Value`, NULL)) AS ''', r.Id, '''' ) ORDER BY r.UpdatedDate ) INTO @SQL 
		FROM
			`new_pb_shieldingpoint` s
			RIGHT JOIN `new_pb_rule` r ON r.Id = s.RuleId
                        WHERE r.ProjectType = projectType
			ORDER BY r.UpdatedDate;

		SET @SQL = CONCAT( 'Select s.Point,
			s.Platform ,
			s.ProjectType,
			s.UpdatorName,
			s.UpdatedDate,', @SQL, ' From new_pb_shieldingpoint s
			RIGHT JOIN `new_pb_rule` r ON r.Id = s.RuleId
			WHERE s.ProjectType = @ProjectType
			GROUP BY s.Point,s.Platform,s.ProjectType
		ORDER BY s.Point,s.Platform,s.ProjectType;' );
		PREPARE stmt 
		FROM
			@SQL;
		EXECUTE stmt;
		DEALLOCATE PREPARE stmt;
END

核心思想是通过GROUP_CONCAT( DISTINCT CONCAT 进行Sql语句的拼接,根据要联查的子表动态生成拼接后的Sql语句,之后再作为静态行转列进行查询,这里有个需要注意的点,如果需要对拼接的动态列进行列的顺序排序,需要写在 GROUP_CONCAT ()内部。

下次要是有人跟我说ORM能解决一切问题、存储过程狗都不写之类的话,我就给他看这个Sql,让他用ORM给我写个这个玩意。

葫芦

葫芦,诞生于1992年8月11日,游戏宅,胶佬,爱好摸鱼,一个干过超市收银,工地里搬过砖,当过广告印刷狗,做过电焊铁艺的现役.Net程序员。

发表回复