简体   繁体   中英

how to make row values to column dynamically in mysql

i want to get each tank value date wise but dynamically.bcoz more tank may be added in future.

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`);

Table Name: 'tank'

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

Table Name:'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

The wanted result of the sql query, the rows sjould end in 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

As nobody else has answered. I give you my idea. Basis for all is

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');

From that i build first a static Sql statement

 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  ;

And from that i build a stored procedure with a loop

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

You can call it by using call procedure_Receipt_Tank(); I personally would add a time frame in which you want the data For this you add to the stored procedure datefrom date and you have alo to add a date to the call procedure. the biggest Problem is that this stored procedure builds a Select statement, which it executes at the end. tempvar is longtext and can be up to 4 gb

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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