繁体   English   中英

如何在mysql中动态地使行值到列

[英]how to make row values to column dynamically in mysql

我想明智地获取每个储罐价值日期,但dynamic.bcoz将来可能会添加更多储罐。

SET SESSION group_concat_max_len = 1000000;
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
CONCAT(
  'MAX(CASE WHEN f1.Tank_ID= ''',
  f1.Tank_ID,
  ''' THEN nf1.'Receipt' END) AS '
  f1.Tank
)
)INTO @sql
FROM  
tank_details AS nf1 
    RIGHT JOIN
tank AS f1 ON f1.Tank_ID = nf1.Tank_ID
group by DATE(`Date`);

表格名称:“ tank”

Tank_ID      Tank
1            Tank 1
2            Tank 2
3            Tank 3
4            Tank 4
5            Tank 5

表名称:'tank_details'

Tank_ID    Receipt    Date
1          1000       2019-07-10
2          2000       2019-07-10
3          3000       2019-07-10
1           0         2019-07-10
1           0         2019-07-15
3           0         2019-07-15
2           0         2019-07-15
3           0         2019-07-15
1           250       2019-07-15
2           200       2019-07-15
3           800       2019-07-15
1           250       2019-07-15
4           350       2019-07-15
1           0         2019-07-20
2           0         2019-07-20
3           0         2019-07-20
4           0         2019-07-20
1           300       2019-07-20
2          1200       2019-07-20
3          1400       2019-07-20
4          900        2019-07-20
5           20        2019-07-20
1          500        2019-07-20

sql查询的所需结果,行应以clomuns结尾。

Date         Receipt      Tank 1    Tank 2   Tank 3    Tank 4     Tank 5
2019-07-10    6000         1000     2000     3000       NULL       NULL
2019-07-15    1850         500       200      800       350        NULL
2019-07-20    4320         800      1200     1400       900        20

正如没有人回答。 我给你我的主意。 一切的基础是

CREATE TABLE tank
(`Tank_ID` int, `Tank` varchar(6))
;

INSERT INTO tank
(`Tank_ID`, `Tank`)
VALUES
(1, 'Tank 1'),
(2, 'Tank 2'),
(3, 'Tank 3'),
(4, 'Tank 4'),
(5, 'Tank 5');

CREATE TABLE tank_detail
(`Tank_ID` int, `Receipt` int, `Date` date);

INSERT INTO tank_detail
(`Tank_ID`, `Receipt`, `Date`)
VALUES
(1, 1000, '2019-07-10'),
(2, 2000, '2019-07-10'),
(3, 3000, '2019-07-10'),
(1, 0, '2019-07-10'),
(1, 0, '2019-07-15'),
(3, 0, '2019-07-15'),
(2, 0, '2019-07-15'),
(3, 0, '2019-07-15'),
(1, 250, '2019-07-15'),
(2, 200, '2019-07-15'),
(3, 800, '2019-07-15'),
(1, 250, '2019-07-15'),
(4, 350, '2019-07-15'),
(1, 0, '2019-07-20'),
(2, 0, '2019-07-20'),
(3, 0, '2019-07-20'),
(4, 0, '2019-07-20'),
(1, 300, '2019-07-20'),
(2, 1200, '2019-07-20'),
(3, 1400, '2019-07-20'),
(4, 900, '2019-07-20'),
(5, 20, '2019-07-20'),
(1, 500, '2019-07-20');

从那我首先建立一个静态的SQL语句

 Select Date,Sum(recsum) as Receipt
  , Sum(a1) as 'Tanl 1'
  , Sum(a2) as 'Tanl 2'
  , Sum(a3) as 'Tank 3'
  , Sum(a4) as 'Tanl 4'
  , Sum(a5) as 'Tanl 5'
 From
  (Select tank_detail.Tank_ID tankid,Date,Sum(Receipt) recsum
   , if (tank_detail.Tank_ID = 1, Sum(Receipt),0) as a1
   , if (tank_detail.Tank_ID = 2, Sum(Receipt),0) as a2
   , if (tank_detail.Tank_ID = 3, Sum(Receipt),0) as a3
   , if (tank_detail.Tank_ID = 4, Sum(Receipt),0) as a4
   , if (tank_detail.Tank_ID = 5, Sum(Receipt),0) as a5
  From tank_detail 
  Group by tank_detail.Tank_ID,Date) td1
 Group by Date  ;

然后我用一个循环建立一个存储过程

CREATE DEFINER=`root`@`localhost` PROCEDURE `procedure_Receipt_Tank`()
BEGIN
DECLARE bDone int DEFAULT 0;
DECLARE tanknumber int DEFAULT 0;
DECLARE tabkname VARCHAR(10);
DECLARE Tempvar LONGTEXT DeFAULT '';
DECLARE Tempvar2 LONGTEXT DeFAULT '';

DECLARE curs1 CURSOR FOR SELECT Tank_ID,Tank From tank;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;

OPEN curs1;
SET Tempvar = CONCAT(Tempvar , 'Select Date,Sum(recsum) as Receipt ');
SET Tempvar2 = CONCAT(Tempvar2 , ' From ');
SET Tempvar2 = CONCAT(Tempvar2 , '(Select tank_detail.Tank_ID
tankid,Date,Sum(Receipt) recsum ');
read_loop: LOOP

    FETCH curs1 INTO tanknumber,tabkname;
    IF bDone = 1 THEN
        LEAVE read_loop;
    END IF;        
    SET Tempvar = CONCAT(Tempvar , ' , Sum(a',tanknumber,') as "',tabkname,'"');
    SET Tempvar2 = CONCAT(Tempvar2 , ', if (tank_detail.Tank_ID = ',tanknumber,',
    Sum(Receipt),0) as a',tanknumber,' ');
 END LOOP read_loop;
CLOSE curs1;
SET Tempvar = CONCAT(Tempvar ,Tempvar2,' From tank_detail ');
SET Tempvar = CONCAT(Tempvar ,' Group by tank_detail.Tank_ID,Date) td1');
SET Tempvar = CONCAT(Tempvar ,' Group by Date;');
SET @v_Query =  '';
SET @v_Query = CONCAT(@v_Query ,  Tempvar);
PREPARE stmt FROM @v_Query;
execute stmt;
#Select Tempvar;        
END

您可以通过调用procedure_Receipt_Tank()来调用它。 我个人将在其中添加数据的时间范围。为此,您将数据添加到存储过程datefrom date中,并且还可以向调用过程中添加日期。 最大的问题是该存储过程会生成一个Select语句,并在最后执行该语句。 tempvar是longtext,最大可为4 GB

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM