MYSQL 动态查询结果

今天遇到一个需求需要把这样的

MYSQL 动态查询结果_第1张图片

转化为这样的

第一张图是从临时表来的,也就是第二个图的列名是不固定的,如果列名是固定的就是一个简单的行转列,但是现在列名不固定,我们必须使用动态的行转列, 完成这个装换我们需要使用两个知识点

1. 使用动态语句执行sql

SET @sql = CONCAT("CREATE TEMPORARY TABLE dy_table( ser_no varchar(40) null,", @partial_sql, ");");
PREPARE stmt FROM @sql;
EXECUTE stmt;

2. 实现行转列

SELECT order_no, order_type,
MAX(CASE WHEN profile_type ='ASSY_LOC'  AND profile_cat='MPS'  THEN profile_c ELSE NULL  END) AS 'assyLoc',
MAX(CASE WHEN profile_type ='SHIFT'  AND profile_cat='MPS'  THEN profile_c ELSE NULL  END) AS 'shif',
MAX(CASE WHEN profile_type ='PRIORITY'  AND profile_cat='MPS'  THEN profile_c ELSE NULL  END) AS 'priority',
MAX(CASE WHEN profile_type ='REL_DATE'  AND profile_cat='MPS'  THEN profile_d ELSE NULL  END) AS 'releaseDate',
FROM test
WHERE test_type = 28 
AND test_no IN(10504530, 10530423) 
GROUP BY test_no , test_type 

因为需求中有一部分列是固定的,有一部分列是不固定的,我们需要把不固定的列插入一个临时表中,最后和固定的列以及join查出来。大概思路:

1. 将value_s列进行拆分,使用字符串把字段名,和值拆分到一个临时表中

2. 根据字段名去重,构建临时表的创建sql, 和插入sql

3. 执行构建的sql.

完整代码

DROP TEMPORARY TABLE
 
IF EXISTS assy_detail;

DROP TEMPORARY TABLE
 
IF EXISTS dy_table;

DROP TEMPORARY TABLE
 
IF EXISTS create_dy_table;

DROP TEMPORARY TABLE
 
IF EXISTS dy_column;

CREATE TEMPORARY TABLE assy_detail(
        ser_no  VARCHAR(100) NULL,
        value_s VARCHAR(100) NULL
);

CREATE TEMPORARY TABLE create_dy_table(
        cloumn_name  VARCHAR(100) NULL,
		create_table_sql VARCHAR(100) NULL,
		insert_data_sql VARCHAR(100) NULL
);

CREATE TEMPORARY TABLE dy_column(
    ser_no varchar(40) NULL
    ,value_s VARCHAR(256) NULL
    ,dy_query_sql varchar(100) NULL
    ,cloumn_name varchar(50) NULL
    ,cloumn_value varchar(30) NULL
    );

insert into assy_detail(ser_no,value_s) values ('123', '姓名:张三');
insert into assy_detail(ser_no,value_s) values ('123', '性别:男');
insert into assy_detail(ser_no,value_s) values ('123', '学历:本科');
insert into assy_detail(ser_no,value_s) values ('1233', '学历:本科');


select * from assy_detail;

/*1. create TEMPORARY TABLE dy_table */
insert into create_dy_table(
   cloumn_name
)
SELECT distinct REPLACE(SUBSTRING(value_s, 1, locate(":", value_s) - 1), '-', '_')  
FROM assy_detail;


update create_dy_table
set create_table_sql = CONCAT(cloumn_name, ' varchar(100) null '),
    insert_data_sql = CONCAT(' MAX(CASE WHEN cloumn_name = ', '\'', cloumn_name, '\'', ' THEN ', 'cloumn_value ', ' ELSE NULL END) AS ', '\'',  cloumn_name, '\'');


set @partial_sql = (
    SELECT GROUP_CONCAT(create_table_sql)
    FROM create_dy_table
);
SET @sql = CONCAT("CREATE TEMPORARY TABLE dy_table( ser_no varchar(40) null,", @partial_sql, ");");
PREPARE stmt FROM @sql;
EXECUTE stmt;

/*2 insert data into dy_table*/
INSERT INTO dy_column(
     ser_no
    ,value_s
    ,cloumn_name
    ,cloumn_value
    )
SELECT distinct 
     ser_no
    ,value_s
    ,REPLACE(SUBSTRING(value_s, 1, locate(":", value_s) - 1), '-', '_')
    ,SUBSTRING(value_s, locate(":", value_s) + 1)
FROM assy_detail;

set @partial_sql = (
    SELECT GROUP_CONCAT(insert_data_sql)
    FROM create_dy_table
);
set @sql = concat('insert into dy_table select ser_no, ',@partial_sql, ' from dy_column group by ser_no;');
 
PREPARE stmt FROM @sql;
EXECUTE stmt;

select * from dy_table;

 

你可能感兴趣的:(Java8)