[MySQL] 行列轉換變化各種方法實現總結(行變列報表統計、列變行資料記錄統計等)
前言:
mysql行列變化,最難的就是將多個列變成多行,使用的比較多的是統計學中行變列,列變行,沒有找到現成的函式或者語句,所以自己寫了儲存過程,使用動態sql來實現,應用業務場景,使用者每個月都有使用記錄數錄入一張表,一個月一個欄位,所以表的欄位是動態增長的,現在需要實時統計當前使用者使用的總數量,如果你知道有多少個欄位,那麼可以用select c1+c2+c3+…. From tbname where tid=’111’;來實現,但是關鍵是這個都是動態的,所以在應用程式端來實現確實不適宜,可以放在資料庫後臺在儲存過程裡實現。
而且在行變成列中,如果要寫單個sql來實現,列的數目就需要寫死,因為如果不知道要展示成多少列的話,就需要用動態變數,而一條
一,列變成行例子演示
1,準備測試資料
這是基礎資料表,裡面有多個欄位wm201403……,現在需要把N個這樣的列變成行資料。
USE csdn; DROP TABLE IF EXISTS flow_table; CREATE TABLE `flow_table` ( `ID` INT(11) NOT NULL AUTO_INCREMENT, `Number` BIGINT(11) NOT NULL, `City` VARCHAR(10) NOT NULL, `wm201403` DECIMAL(7,2) DEFAULT NULL, `wm201404` DECIMAL(7,2) DEFAULT NULL, `wm201405` DECIMAL(7,2) DEFAULT NULL, `wm201406` DECIMAL(7,2) DEFAULT NULL, `wm201407` DECIMAL(7,2) DEFAULT NULL, `wm201408` DECIMAL(7,2) DEFAULT NULL, PRIMARY KEY (`ID`,`Number`) ) ENGINE=INNODB DEFAULT CHARSET=utf8;
錄入一批測試資料:
INSERT INTO flow_table(Number,City,wm201403,wm201404,wm201405,wm201406,wm201407,wm201408)SELECT 1,'shanghai',100.2,180.4,141,164,124,127; INSERT INTO flow_table(Number,City,wm201403,wm201404,wm201405,wm201406,wm201407,wm201408)SELECT 2,'shanghai',110.23,180.34,141.23,104.78,124.67,127.45; INSERT INTO flow_table(Number,City,wm201403,wm201404,wm201405,wm201406,wm201407,wm201408)SELECT 3,'beijing',123.23,110.34,131.33,154.58,154.67,167.45; INSERT INTO flow_table(Number,City,wm201403,wm201404,wm201405,wm201406,wm201407,wm201408)SELECT 4,'hangzhou',0,110.34,131.33,154.58,154.67,0; INSERT INTO flow_table(Number,City,wm201405,wm201406,wm201407,wm201408)SELECT 5,'hangzhou',131.33,154.58,154.67,0;
需要達到的統計效果是:
+--------+-----------+
| Number | total_num |
+--------+-----------+
| 1 | 836.60 |
| 2 | 788.70 |
| 3 | 841.60 |
| 4 | 550.92 |
| 5 | 440.58 |
+--------+-----------+
5 rows in set (0.00 sec)
2,儲存過程遍歷:
這個儲存過程建立了2張臨時表,查詢測試表資料形成遊標,遍歷遊標根據主鍵Number來呼叫pro_flow_modify儲存過程進行行列變化。程式碼如下:
DELIMITER $$
DROP PROCEDURE IF EXISTS csdn.`proc_all_changes`$$
CREATE PROCEDURE csdn.proc_all_changes()
BEGIN
DECLARE v_number BIGINT;
DECLARE v_city VARCHAR(10);
DECLARE _done INT DEFAULT 0;
/*定義遊標*/
DECLARE cur_all CURSOR FOR SELECT Number,City FROM csdn.`flow_table`;
/**這裡如果需要定義下當NOT FOUND的時候,EXIT退出遊標遍歷,不然如果設定成CONTINUE會一直執行下去。*/
DECLARE EXIT HANDLER FOR NOT FOUND BEGIN SET _done=1;END;
/*建立臨時表,存放所有欄位的臨時表*/
DROP TABLE IF EXISTS flow_n_columns;
CREATE TABLE `flow_n_columns` (
`column_name` VARCHAR(10) NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
/*存放最終變成行的資料表*/
DROP TABLE IF EXISTS flow_tmp;
CREATE TABLE `flow_tmp` (
`Number` INT(11) DEFAULT NULL,
`City` VARCHAR(10) DEFAULT NULL,
`wm_str` VARCHAR(10) DEFAULT NULL,
`Wm` DECIMAL(7,2) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
OPEN cur_all;
REPEAT
FETCH cur_all INTO v_number, v_city;
IF NOT _done THEN
CALL csdn.pro_flow_modify(v_number,v_city);
END IF;
UNTIL _done=1 END REPEAT;
CLOSE cur_all;
/*展示下所有的行轉列的資料**/
SELECT * FROM csdn.flow_tmp;
END$$
DELIMITER ;
3,行裡變化儲存過程
通過查詢系統表information_schema.`COLUMNS`來獲取測試表flow_table的所有列,然後寫動態SQL,來把列的值錄入到臨時表flow_tmp中。
DELIMITER $$
DROP PROCEDURE IF EXISTS csdn.`pro_flow_modify`$$
CREATE PROCEDURE csdn.`pro_flow_modify`(p_Number INT,p_city VARCHAR(10))
BEGIN
DECLARE v_column_name VARCHAR(10) DEFAULT '';
DECLARE v_exe_sql VARCHAR(1000) DEFAULT '';
DECLARE v_start_wm VARCHAR(10) DEFAULT '';
DECLARE v_end_wm VARCHAR(10) DEFAULT '';
DECLARE v_num DECIMAL(10,2) DEFAULT 0;
DECLARE i INT DEFAULT 1;
DECLARE v_Number INT DEFAULT 0;
SET v_Number=p_Number;
DELETE FROM csdn.flow_n_columns;
DELETE FROM csdn.flow_tmp WHERE Number=v_Number;
/*把測試表flow_table的所有欄位都錄入欄位臨時表中,這樣就達到了從列變成行的目的*/
INSERT INTO flow_n_columns
SELECT t.`COLUMN_NAME` FROM information_schema.`COLUMNS` t WHERE t.`TABLE_NAME`='flow_table' AND t.`TABLE_SCHEMA`='csdn' AND t.`COLUMN_NAME` NOT IN('ID','Number','City');
SELECT column_name INTO v_column_name FROM csdn.flow_n_columns LIMIT 1;
/*開始迴圈遍歷欄位臨時表的欄位資料,並且把欄位值放入臨時表flow_tmp裡面*/
WHILE i>0 DO
SET v_exe_sql=CONCAT('INSERT INTO csdn.flow_tmp(Number,City,wm_str,Wm) select ',v_Number,',\'',p_city, '\',\'',v_column_name,'\',',v_column_name,' from csdn.flow_table WHERE flow_table.Number=',v_Number,';');
SET @sql=v_exe_sql;
PREPARE s1 FROM @sql;
EXECUTE s1;
DEALLOCATE PREPARE s1;
DELETE FROM csdn.flow_n_columns WHERE column_name=v_column_name;
SELECT column_name INTO v_column_name FROM csdn.flow_n_columns LIMIT 1;
SELECT COUNT(1) INTO i FROM csdn.flow_n_columns ;
DELETE FROM csdn.flow_tmp WHERE Wm=0;
END WHILE;
/*由於觸發器是不支援動態sql,所以不能使用while迴圈,動態遍歷所有統計列的,只能寫死列了,如下所示:
現在一個個insert只能寫死了, flow_table表有多少個統計列就寫多少個insert sql,以後新新增一個列,就在這裡新新增一條insertsql語句
INSERT INTO flow_tmp(Number,City,wm_str,Wm) SELECT v_Number,p_city,'wm201403',wm201403 FROM flow_table WHERE Number=v_Number ;
INSERT INTO flow_tmp(Number,City,wm_str,Wm) SELECT v_Number,p_city,'wm201404',wm201404 FROM flow_table WHERE Number=v_Number ;
INSERT INTO flow_tmp(Number,City,wm_str,Wm) SELECT v_Number,p_city,'wm201405',wm201405 FROM flow_table WHERE Number=v_Number ;
INSERT INTO flow_tmp(Number,City,wm_str,Wm) SELECT v_Number,p_city,'wm201406',wm201406 FROM flow_table WHERE Number=v_Number ;
INSERT INTO flow_tmp(Number,City,wm_str,Wm) SELECT v_Number,p_city,'wm201407',wm201407 FROM flow_table WHERE Number=v_Number ;
INSERT INTO flow_tmp(Number,City,wm_str,Wm) SELECT v_Number,p_city,'wm201408',wm201408 FROM flow_table WHERE Number=v_Number ;
*/
/*清除掉不資料=0的列*/
DELETE FROM csdn.flow_tmp WHERE Wm=0 OR Wm IS NULL;
SELECT wm_str INTO v_start_wm FROM csdn.flow_tmp WHERE Number=v_Number ORDER BY wm_str ASC LIMIT 1;
SELECT wm_str INTO v_end_wm FROM csdn.flow_tmp WHERE Number=v_Number ORDER BY wm_str DESC LIMIT 1;
SELECT SUM(Wm) INTO v_num FROM csdn.flow_tmp WHERE Number=v_Number;
END$$
DELIMITER ;
4,列變行結果展示
臨時表的所有資料:
mysql> SELECT * FROM csdn.flow_tmp;
+--------+----------+----------+--------+
| Number | City | wm_str | Wm |
+--------+----------+----------+--------+
| 1 | shanghai | wm201403 | 100.20 |
| 1 | shanghai | wm201404 | 180.40 |
| 1 | shanghai | wm201405 | 141.00 |
| 1 | shanghai | wm201406 | 164.00 |
| 1 | shanghai | wm201407 | 124.00 |
| 1 | shanghai | wm201408 | 127.00 |
| 2 | shanghai | wm201403 | 110.23 |
| 2 | shanghai | wm201404 | 180.34 |
| 2 | shanghai | wm201405 | 141.23 |
| 2 | shanghai | wm201406 | 104.78 |
| 2 | shanghai | wm201407 | 124.67 |
| 2 | shanghai | wm201408 | 127.45 |
| 3 | beijing | wm201403 | 123.23 |
| 3 | beijing | wm201404 | 110.34 |
| 3 | beijing | wm201405 | 131.33 |
| 3 | beijing | wm201406 | 154.58 |
| 3 | beijing | wm201407 | 154.67 |
| 3 | beijing | wm201408 | 167.45 |
| 4 | hangzhou | wm201404 | 110.34 |
| 4 | hangzhou | wm201405 | 131.33 |
| 4 | hangzhou | wm201406 | 154.58 |
| 4 | hangzhou | wm201407 | 154.67 |
| 5 | hangzhou | wm201405 | 131.33 |
| 5 | hangzhou | wm201406 | 154.58 |
| 5 | hangzhou | wm201407 | 154.67 |
+--------+----------+----------+--------+
25 rows in set (0.00 sec)
mysql>
統計每個使用者的使用總量為:
mysql> SELECT Number,SUM(Wm) 'total_num' FROM flow_tmp GROUP BY Number ORDER BY Number;
+--------+-----------+
| Number | total_num |
+--------+-----------+
| 1 | 836.60 |
| 2 | 788.70 |
| 3 | 841.60 |
| 4 | 550.92 |
| 5 | 440.58 |
+--------+-----------+
5 rows in set (0.00 sec)
mysql>
二,行變列例子演示
1,準備測試資料
USE csdn;
DROP TABLE IF EXISTS csdn.tb;
CREATE TABLE tb(`cname` VARCHAR(10),cource VARCHAR(10),score INT) ENGINE=INNODB;
INSERT INTO tb VALUES('張三','語文',74);
INSERT INTO tb VALUES('張三','數學',83);
INSERT INTO tb VALUES('張三','物理',93);
INSERT INTO tb VALUES('李四','語文',74);
INSERT INTO tb VALUES('李四','數學',84);
INSERT INTO tb VALUES('李四','物理',94);
SELECT * FROM tb;
需要得到的結果是:
+--------------------+--------+--------+--------+-----------+--------------+
| 姓名 | 語文 | 數學 | 物理 | 總成績 | 平均成績 |
+--------------------+--------+--------+--------+-----------+--------------+
| 張三 | 74.00 | 83.00 | 93.00 | 250.00 | 83.33 |
| 李四 | 74.00 | 84.00 | 94.00 | 252.00 | 84.00 |
| 總成績平均數 | 74.00 | 83.50 | 93.50 | 251.00 | 83.67 |
+--------------------+--------+--------+--------+-----------+--------------+
2,利用SUM(IF()) 生成列 + WITH ROLLUP 生成彙總行,並利用 IFNULL將彙總行標題顯示為 Total_num
SQL程式碼塊如下:
SELECT cname AS "姓名",
SUM(IF(cource="語文",score,0)) AS "語文",
SUM(IF(cource="數學",score,0)) AS "數學",
SUM(IF(cource="物理",score,0)) AS "物理",
SUM(score) AS "總成績",
ROUND(AVG(score),2) AS "平均成績"
FROM tb
GROUP BY cname
UNION ALL
SELECT
"總成績平均數",
ROUND(AVG(`語文`),2) , ROUND(AVG(`數學`),2), ROUND(AVG(`物理`),2), ROUND(AVG(`總成績`),2), ROUND(AVG(`平均成績`),2)
FROM(
SELECT "all",cname AS "姓名",
SUM(IF(cource="語文",score,0)) AS "語文",
SUM(IF(cource="數學",score,0)) AS "數學",
SUM(IF(cource="物理",score,0)) AS "物理",
SUM(score) AS "總成績",
AVG(score) AS "平均成績"
FROM tb
GROUP BY cname
)tb2
GROUP BY tb2.all;
執行結果正確,如下所示:
+--------------------+--------+--------+--------+-----------+--------------+
| 姓名 | 語文 | 數學 | 物理 | 總成績 | 平均成績 |
+--------------------+--------+--------+--------+-----------+--------------+
| 張三 | 74.00 | 83.00 | 93.00 | 250.00 | 83.33 |
| 李四 | 74.00 | 84.00 | 94.00 | 252.00 | 84.00 |
| 總成績平均數 | 74.00 | 83.50 | 93.50 | 251.00 | 83.67 |
+--------------------+--------+--------+--------+-----------+--------------+
3,利用max(CASE ... WHEN ... THEN .. ELSE END) AS "語文"的方式來實現
SQL程式碼如下:
SELECT
cname AS "姓名",
MAX(CASE cource WHEN "語文" THEN score ELSE 0 END) AS "語文",
MAX(CASE cource WHEN "數學" THEN score ELSE 0 END) AS "數學",
MAX(CASE cource WHEN "物理" THEN score ELSE 0 END) AS "物理",
SUM(score) AS "總成績",
ROUND(AVG(score) ,2) AS "平均成績"
FROM tb
GROUP BY `cname`
UNION ALL
SELECT
"總成績平均數",
ROUND(AVG(`語文`),2) , ROUND(AVG(`數學`),2), ROUND(AVG(`物理`),2), ROUND(AVG(`總成績`),2), ROUND(AVG(`平均成績`),2)
FROM( SELECT 'all' ,
cname AS "姓名",
MAX(CASE cource WHEN "語文" THEN score ELSE 0 END) AS "語文",
MAX(CASE cource WHEN "數學" THEN score ELSE 0 END) AS "數學",
MAX(CASE cource WHEN "物理" THEN score ELSE 0 END) AS "物理",
SUM(score) AS "總成績",
ROUND(AVG(score) ,2) AS "平均成績"
FROM tb
GROUP BY `cname`
)tb2 GROUP BY tb2.all
執行結果正確,如下所示:
+--------------------+--------+--------+--------+-----------+--------------+
| 姓名 | 語文 | 數學 | 物理 | 總成績 | 平均成績 |
+--------------------+--------+--------+--------+-----------+--------------+
| 張三 | 74.00 | 83.00 | 93.00 | 250.00 | 83.33 |
| 李四 | 74.00 | 84.00 | 94.00 | 252.00 | 84.00 |
| 總成績平均數 | 74.00 | 83.50 | 93.50 | 251.00 | 83.67 |
+--------------------+--------+--------+--------+-----------+--------------+
4,利用 WITH rollup結果不符合
SQL程式碼如下: SELECT IFNULL(cname,'總平均數') AS "姓名",
MAX(CASE cource WHEN "語文" THEN score ELSE 0 END) AS "語文",
MAX(CASE cource WHEN "數學" THEN score ELSE 0 END) AS "數學",
MAX(CASE cource WHEN "物理" THEN score ELSE 0 END) AS "物理",
ROUND(AVG(score),2) AS "總成績",
ROUND(AVG(avg_score),2) AS "平均成績"
FROM(
SELECT
cname ,
IFNULL(cource,'total') cource,
SUM(score) AS score,
ROUND(AVG(score) ,2) AS avg_score
FROM tb
GROUP BY `cname`,cource WITH ROLLUP HAVING cname IS NOT NULL
)tb2
GROUP BY tb2.cname WITH ROLLUP;
執行結果不對,總平均數欄目,裡面各科比較語文數學的班級平均數不對,如下所示:
mysql> SELECT IFNULL(cname,'總平均數') AS "姓名",
-> MAX(CASE cource WHEN "語文" THEN score ELSE 0 END) AS "語文",
-> MAX(CASE cource WHEN "數學" THEN score ELSE 0 END) AS "數學",
-> MAX(CASE cource WHEN "物理" THEN score ELSE 0 END) AS "物理",
-> ROUND(AVG(score),2) AS "總成績",
-> ROUND(AVG(avg_score),2) AS "平均成績"
-> FROM(
-> SELECT
->
Display ALL 793 possibilities? (Y OR n)
-> cname ,
->
Display ALL 793 possibilities? (Y OR n)
-> IFNULL(cource,'total') cource,
->
Display ALL 793 possibilities? (Y OR n)
-> SUM(score) AS score,
->
Display ALL 793 possibilities? (Y OR n)
-> ROUND(AVG(score) ,2) AS avg_score
-> FROM tb
-> GROUP BY `cname`,cource WITH ROLLUP HAVING cname IS NOT NULL
-> )tb2
-> GROUP BY tb2.cname WITH ROLLUP;
+--------------+--------+--------+--------+-----------+--------------+
| 姓名 | 語文 | 數學 | 物理 | 總成績 | 平均成績 |
+--------------+--------+--------+--------+-----------+--------------+
| 張三 | 74 | 83 | 93 | 125.00 | 83.33 |
| 李四 | 74 | 84 | 94 | 126.00 | 84.00 |
| 總平均數 | 74 | 84 | 94 | 125.50 | 83.67 |
+--------------+--------+--------+--------+-----------+--------------+
3 ROWS IN SET, 1 warning (0.00 sec)
mysql>
總結: WITH rollup中對求列的總數是OK的,但是求列的平均數有偏差,這裡場景使用不是恰當。
5,使用動態SQL來實現
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 行列轉換變化各種方法實現總結(行變列報表統計 列變行資料記錄統計等)
前言:mysql行列變化,最難的就是將多個列變成多行,使用的比較多的是統計學中行變列,列變行,沒有找到現成的函式或者語句,所以自己寫了儲存過程,使用動態sql來實現,應用業務場景,使用者每個月都有使用記錄數錄入一張表,一個月一個欄位,所以表的欄位是動態增長的,現在需要實時統計當
[MySQL] 行列轉換變化各種方法實現總結(行變列報表統計、列變行資料記錄統計等)
前言:mysql行列變化,最難的就是將多個列變成多行,使用的比較多的是統計學中行變列,列變行,沒有找到現成的函式或者語句,所以自己寫了儲存過程,使用動態sql來實現,應用業務場景,使用者每個月都有使用記錄數錄入一張表,一個月一個欄位,所以表的欄位是動態增長的,現在需要實時統計
[MySQL] 行列轉換變化各種方法實現總結(行變列報表統計、列變行資料記錄統計等
前言: mysql行列變化,最難的就是將多個列變成多行,使用的比較多的是統計學中行變列,列變行,沒有找到現成的函式或者語句,所以自己寫了儲存過程,使用動態sql來實現,應用業務場景,使用者每個月都有使用記錄數錄入一張表,一個月一個欄位,所以表的欄位是動態增長的,
Mysql 行列轉換
lec gin name select mysql post with clas price 1、創建表CREATE TABLE `gas` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `oil` VARCHAR(100) N
SQL行列轉換6種方法
ati cin 列名 ada ott 計劃 ase mit all 在進行報表開發時,很多時候會遇到行列轉換操作,很對開發人員針對於SQL級別行列轉換操作一直不甚理解,今天正好抽空對其進行了一些簡單的總結。這裏主要列舉3種可以實現SQL行列轉換的方法,包括通用SQL解法以及
前端面試中的各種方法實現
最近在面試,面試官動不動就讓寫一個原生方法的實現,那咱們就在這裡寫一下常見的一些實現: 1.bind Function.prototype.bind2 = function (context) { var self = this; return fu
關於HsahMap的各種方法使用總結
1,map是與collection同級的介面,我們常用它的HashMap實現類HashMap是通過鍵值對應的關係來儲存資訊的,與我們之前的list和set都不一樣每一個key都對應一個value,可以儲存不同的物件我們獲取它儲存的value就只能通過get(key)方法來獲取
動態mysql行列轉換
一,列變成行例子演示1,準備測試資料USE csdn; DROP TABLE IF EXISTS flow_table; CREATE TABLE `flow_table` ( `ID` INT(11) NOT NULL AUTO_INCREMENT, `Number
mysql行列轉換示例
現把轉換方法列舉如下: 1、縱錶轉橫表: 縱表結構 TableA Name Course Grade 張三 語文 75 張三 數學 80 張三 英語 90 李四 語文 95 李四 數學
資料結構與演算法(2)——各種方法實現楊輝三角
分別用二維陣列、一維陣列、遞迴等三種方法實現楊輝三角; 楊輝三角:首尾都為1,中間數值等於其肩上兩個數值之和,形如下面: 1
String 常用方法最優演算法實現總結 (三) -- findCommonSubstring 和difference
1. String difference(final String str1, final String str2) 說明:Compares two Strings, and returns the portion where they differ. i.e: ("ahc
mybatis collection 多條件查詢 結合mysql行列轉換
需求:查詢訂單列表,一個訂單 包括訂單號,訂單id.,訂單下的商品列表...等等,訂單的商品列表為N個商品,每個商品包括商品的 id ,名稱,金額,兩個繳費類(商品原因,分為兩種費用,資料庫欄位同一個,繳費型別不同 1,2,所以每個商品其實也是一個兩條記錄的列表,但需求為 兩
String 經常用法最優算法實現總結 (二)
lean ... itl min empty turn system then 實現 1. String getOrderedString(boolean isDuplicated, String … str) 說明: Orders all characters in
C#中WinForm程序退出方法技巧總結 (轉)
ren sender body 登錄 ble 按鈕 動作 打開 alt 一、關閉窗體 在c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();Application.ExitThread(); System.E
C#中WinForm程序退出方法技巧總結(轉)
sys 返回 展開 退出程序 結束 所有 body rgs cat 本文實例總結了C#中WinForm程序退出方法技巧。分享給大家供大家參考。具體分析如下: 在c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();
java+selenium的使用方法歸納總結(持續更新中)
selenium的使用 第一步:獲取selenium的jar包及驅動瀏覽器的驅動 在獲取selenium的jar包和瀏覽器的驅動包時,要對照她們的版本號 通過下面可檢視谷歌的版本對應 java+selenium的入門 案例 selenium包 谷歌驅動包 火狐驅動包 IE驅動包
遞迴方法實現深度克隆原理:遍歷物件、陣列直到裡邊都是基本資料型別,然後再去複製,就是深度拷貝。
手寫遞迴方法 //定義檢測資料型別的功能函式 function checkedType(target) { return Object.prototype.toString.call(target).slice(8, -1) } //實現深度克隆---物件/陣列 function clon
【TensorFlow】優化方法optimizer總結(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)解析(十三)
本文僅對一些常見的優化方法進行直觀介紹和簡單的比較,主要是一階的梯度法,包括SGD, Momentum, Nesterov Momentum, AdaGrad, RMSProp, Adam。 其中SGD,Momentum,Nesterov Momentum是手動
Java程式碼常用功能實現總結(二)
文章目錄 1.如何取得map裡key得最大值: 2.多執行緒寫法樣例: 1.如何取得map裡key得最大值: 方法一: 將Map中的k
關鍵詞提取方法學習總結(TF-IDF、Topic-model、RAKE)
關鍵詞是一篇文件中表達的主要話題,處理文件或句子時,提取關鍵詞是最重要的工作之一,這在NLP中也是一個十分有用的task。 常見的關鍵詞提取方法有:TF-IDF關鍵詞提取方法、Topic-model關鍵詞提取方法和RAKE關鍵詞提取。 TF-IDF: 使用TF-IDF提取