mysql> select
-> ifnull(date,p_name) as date,
-> count(if(p_name='A',1,null)) as A,
-> count(if(p_name='B',2,null)) as B,
-> count(if(p_name='C',3,null)) as C,
-> count(if(p_name='D',4,null)) as D
-> from a left join b on project=id
-> group by date;
+------------+---+---+---+---+
| date | A | B | C | D |
+------------+---+---+---+---+
| 2014-01-01 | 1 | 0 | 0 | 0 |
| 2014-01-02 | 0 | 1 | 1 | 0 |
| 2014-01-04 | 0 | 1 | 0 | 0 |
| 2014-01-05 | 0 | 0 | 0 | 2 |
+------------+---+---+---+---+
4 rows in set, 1 warning (0.00 sec)
-> ifnull(date,p_name) as date,
-> count(if(p_name='A',1,null)) as A,
-> count(if(p_name='B',2,null)) as B,
-> count(if(p_name='C',3,null)) as C,
-> count(if(p_name='D',4,null)) as D
-> from a left join b on project=id
-> group by date;
+------------+---+---+---+---+
| date | A | B | C | D |
+------------+---+---+---+---+
| 2014-01-01 | 1 | 0 | 0 | 0 |
| 2014-01-02 | 0 | 1 | 1 | 0 |
| 2014-01-04 | 0 | 1 | 0 | 0 |
| 2014-01-05 | 0 | 0 | 0 | 2 |
+------------+---+---+---+---+
4 rows in set, 1 warning (0.00 sec)
ifnull(date,p_name) as date,
count(if(p_name='A',id,null)) as A,
count(if(p_name='B',id,null)) as B,
count(if(p_name='C',id,null)) as C,
count(if(p_name='D',id,null)) as D
from
a left join b on project=id
group by date;
SUM(if(B.项目名='A',1,0)) as A,SUM(if(B.项目名='B',1,0)) as B,
SUM(if(B.项目名='C',1,0)) as C,SUM(if(B.项目名='D',1,0)) as D
from a left join b on A.项目=B.id
group by A.`date`
然后select调用就可以了
SQL代码块如下:
/*仅仅班级成员部分*/
SET @a='';
SELECT @a:=CONCAT(@a,'SUM(IF(cource=\'',cource,'\'',',score,0)) AS ',cource,',') FROM (SELECT DISTINCT cource FROM tb) A;
SET @a=CONCAT(@a,"ROUND(AVG(score) ,2) AS \"平均成绩\"");
SET @b=CONCAT('SELECT IFNULL(cname,\'总成绩\'),',LEFT(@a,LENGTH(@a)-1),' ,SUM(score) AS \"总成绩\" FROM tb GROUP BY cname ');
/*班级成员总计部分**/
SET @a2="";
SET @b2=CONCAT('SELECT "all",IFNULL(cname,\'总成绩\'),',LEFT(@a,LENGTH(@a)-1),' ,SUM(score) AS \"总成绩\" FROM tb GROUP BY cname ');
SELECT @a2:=CONCAT(@a2,'ROUND(AVG(`',cource,'`),2),') FROM (SELECT DISTINCT cource FROM tb) A;
SET @a2=CONCAT(@a2," ROUND(AVG(`平均成绩`),2),ROUND(AVG(`总成绩`),2) ");
SET @c=CONCAT("SELECT \"班级平均数\",",LEFT(@a2,LENGTH(@a)-1)," FROM(",@b2,")tb2 GROUP BY tb2.all;");
SET @d=CONCAT(@b," UNION ALL ",@c);
PREPARE stmt1 FROM @d;
EXECUTE stmt1; 查看执行结果如下,已经达到效果:
mysql> /*仅仅班级成员部分*/
mysql> SET @a='';
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SELECT @a:=CONCAT(@a,'SUM(IF(cource=\'',cource,'\'',',score,0)) AS ',cource,',') FROM (SELECT DISTINCT cource FROM tb) A;
+-----------------------------------------------------------------------------------------------------------------------------------+
| @a:=CONCAT(@a,'SUM(IF(cource=\'',cource,'\'',',score,0)) AS ',cource,',') |
+-----------------------------------------------------------------------------------------------------------------------------------+
| SUM(IF(cource='语文',score,0)) AS 语文, |
| SUM(IF(cource='语文',score,0)) AS 语文,SUM(IF(cource='数学',score,0)) AS 数学, |
| SUM(IF(cource='语文',score,0)) AS 语文,SUM(IF(cource='数学',score,0)) AS 数学,SUM(IF(cource='物理',score,0)) AS 物理, |
+-----------------------------------------------------------------------------------------------------------------------------------+
3 ROWS IN SET (0.00 sec)
mysql> SET @a=CONCAT(@a,"ROUND(AVG(score) ,2) AS \"平均成绩\"");
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SET @b=CONCAT('SELECT IFNULL(cname,\'总成绩\'),',LEFT(@a,LENGTH(@a)-1),' ,SUM(score) AS \"总成绩\" FROM tb GROUP BY cname ');
QUERY OK, 0 ROWS affected (0.00 sec)
mysql>
mysql> /*班级成员总计部分**/
mysql> SET @a2="";
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SET @b2=CONCAT('SELECT "all",IFNULL(cname,\'总成绩\'),',LEFT(@a,LENGTH(@a)-1),' ,SUM(score) AS \"总成绩\" FROM tb GROUP BY cname ');
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SELECT @a2:=CONCAT(@a2,'ROUND(AVG(`',cource,'`),2),') FROM (SELECT DISTINCT cource FROM tb) A;
+-----------------------------------------------------------------------+
| @a2:=CONCAT(@a2,'ROUND(AVG(`',cource,'`),2),') |
+-----------------------------------------------------------------------+
| ROUND(AVG(`语文`),2), |
| ROUND(AVG(`语文`),2),ROUND(AVG(`数学`),2), |
| ROUND(AVG(`语文`),2),ROUND(AVG(`数学`),2),ROUND(AVG(`物理`),2), |
+-----------------------------------------------------------------------+
3 ROWS IN SET (0.00 sec)
mysql> SET @a2=CONCAT(@a2," ROUND(AVG(`平均成绩`),2),ROUND(AVG(`总成绩`),2) ");
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SET @c=CONCAT("SELECT \"班级平均数\",",LEFT(@a2,LENGTH(@a)-1)," FROM(",@b2,")tb2 GROUP BY tb2.all;");
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SET @d=CONCAT(@b," UNION ALL ",@c);
QUERY OK, 0 ROWS affected (0.00 sec)
mysql>
mysql> PREPARE stmt1 FROM @d;
QUERY OK, 0 ROWS affected (0.00 sec)
Statement prepared
mysql> EXECUTE stmt1;
+---------------------------+--------+--------+--------+--------------+-----------+
| IFNULL(cname,'总成绩') | 语文 | 数学 | 物理 | 平均成绩 | 总成绩 |
+---------------------------+--------+--------+--------+--------------+-----------+
| 张三 | 74.00 | 83.00 | 93.00 | 83.33 | 250.00 |
| 李四 | 74.00 | 84.00 | 94.00 | 84.00 | 252.00 |
| 班级平均数 | 74.00 | 83.50 | 93.50 | 83.67 | 251.00 |
+---------------------------+--------+--------+--------+--------------+-----------+
3 ROWS IN SET (0.00 sec)
mysql>
mysql> create procedure p_ab()
-> begin
-> declare i,total int;
-> set total=(select count(id) from b);
-> set i=1;
-> set @var=concat('select\nifnull(date,p_name) as date,','\n');
-> while i<=total do
-> set @col=(select p_name from b where id=i);
-> if i!=total then
-> set @var=concat(@var,'count(if(p_name=\'',@col,'\',id,null)) as ',@col,',','\n');
-> else
-> set @var=concat(@var,'count(if(p_name=\'',@col,'\',id,null)) as ',@col,'\n');
-> end if;
-> set i=i+1;
-> end while;
-> set @var=concat(@var,'from\na left join b on project=id\ngroup by date;');
-> prepare ss from @var;
-> execute ss;
-> end$$
Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;
mysql>
mysql> call p_ab;
+------------+---+---+---+---+---+
| date | A | B | C | D | E |
+------------+---+---+---+---+---+
| 2014-01-01 | 2 | 0 | 0 | 0 | 0 |
| 2014-01-02 | 0 | 1 | 1 | 0 | 0 |
| 2014-01-04 | 0 | 1 | 0 | 0 | 0 |
| 2014-01-05 | 0 | 0 | 0 | 2 | 0 |
+------------+---+---+---+---+---+
4 rows in set (0.00 sec)Query OK, 0 rows affected, 1 warning (0.00 sec)
CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_test`()
BEGIN SET @column = '' ;
-- 取出动态列名
SELECT GROUP_CONCAT(CONCAT('SUM(IF(xm = ''' ,xm , ''',1,0)) AS ''',xmmc,''' ') ) INTO @column
FROM test_b ;
-- 生成动态SQL
SET @sql = CONCAT('SELECT rq
,',@column,'
FROM test_a
GROUP BY rq') ;
PREPARE s1 FROM @sql;
EXECUTE s1; DEALLOCATE PREPARE s1; END
MySQL交叉表
在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义。http://topic.csdn.net/u/20090530/23/0b782674-4b0b-4cf5-bc1a-e8914aaee5ab.html?96198现整理解法如下:数据样本: create table tx( id int primary key, c1 c...