mariadb - 如何在 MariaDB 中设置列名,使用动态值
问题描述
我有3个表如下:
tbl_reporting tbl_criteria tbl_student
|===============================| |========================| |===============|
| id | id_criteria | id_student | | id | name |weight | | id | name |
|===============================| |========================| |===============|
| 1 | 2 | 3 | | 1 | worrying | 3 | | 1 | Nina |
| 2 | 1 | 2 | | 2 | naughty | 2 | | 2 | Adam |
| 3 | 1 | 1 | | 3 | usually | 2 | | 3 | Dodi |
| 4 | 2 | 2 | | 4 | good | 1 | | 4 | Zarah |
| 5 | 1 | 1 | | 5 | obey | 1 | | 5 | Udep |
我想要的实际结果如下,计算重量tbl_criteria
result
| student | worrying | naughty | usualy | good | obey | total |
|=============================================================|
| Nina | 6 | 0 | 0 | 0 | 0 | 6 |
| Adam | 3 | 2 | 0 | 0 | 0 | 5 |
| Dodi | 0 | 2 | 0 | 0 | 0 | 2 |
| Zarah | 0 | 0 | 0 | 0 | 0 | 0 |
| Udep | 0 | 0 | 0 | 0 | 0 | 0 |
因此,tbl_criteria.name
字段中的所有值都将成为动态的新列,并计算权重。
我创建了一个表及其输入:http ://sqlfiddle.com/#!9/41e637
v10.3.16-MariaDB
解决方案
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `Pivot`(
IN tbl_name VARCHAR(99), -- table name (or db.tbl)
IN base_cols VARCHAR(99), -- column(s) on the left, separated by commas
IN pivot_col VARCHAR(64), -- name of column to put across the top
IN tally_col VARCHAR(64), -- name of column to SUM up
IN where_clause VARCHAR(99), -- empty string or "WHERE ..."
IN order_by VARCHAR(99) -- empty string or "ORDER BY ..."; usually the base_cols
)
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
-- Find the distinct values
-- Build the SUM()s
SET @subq = CONCAT('SELECT DISTINCT ', pivot_col, ' AS val ',
' FROM ', tbl_name, ' ', where_clause, ' ORDER BY 1');
-- select @subq;
SET @cc1 = "CONCAT('SUM(IF(&p = ', &v, ', &t, 0)) AS ', &v)";
SET @cc2 = REPLACE(@cc1, '&p', pivot_col);
SET @cc3 = REPLACE(@cc2, '&t', tally_col);
-- select @cc2, @cc3;
SET @qval = CONCAT("'\"', val, '\"'");
-- select @qval;
SET @cc4 = REPLACE(@cc3, '&v', @qval);
-- select @cc4;
SET SESSION group_concat_max_len = 10000; -- just in case
SET @stmt = CONCAT(
'SELECT GROUP_CONCAT(', @cc4, ' SEPARATOR ",\n") INTO @sums',
' FROM ( ', @subq, ' ) AS top');
select @stmt;
PREPARE _sql FROM @stmt;
EXECUTE _sql; -- Intermediate step: build SQL for columns
DEALLOCATE PREPARE _sql;
-- Construct the query and perform it
SET @stmt2 = CONCAT(
'SELECT ',
base_cols, ',\n',
@sums,
',\n SUM(', tally_col, ') AS Total'
'\n FROM ', tbl_name, ' ',
where_clause,
' GROUP BY ', base_cols,
'\n WITH ROLLUP',
'\n', order_by
);
select @stmt2; -- The statement that generates the result
PREPARE _sql FROM @stmt2;
EXECUTE _sql; -- The resulting pivot table ouput
DEALLOCATE PREPARE _sql;
-- For debugging / tweaking, SELECT the various @variables after CALLing.
END$$
DELIMITER ;
推荐阅读
- ansible - 使用ansible循环主机变量
- google-apps-script - 在 getvalue() Google 表格中排除带有空白单元格的行
- react-native - React 本机应用程序未检测到订阅是否有效
- python - 在日志文件中每一行的开头打印特定的字符串
- java - java在javafx项目的intellij中找不到方法setTitle()和show()(在Ubuntu机器中)
- java - Spring Boot 测试和 Jackson - 在测试中从上下文设置 (application.yml) 中获取 ObjectMapper 的实例,无需开销配置
- sql - 如何在单个列上使用 distinct 并在 bigquery 中返回多个其他列?
- android - 电话响铃时会发生哪个活动生命周期?
- python - 我尝试了其他方法,但我仍然犯了错误。TypeError:'str' object is not callable
- python-3.x - 获取与同一列下的两个值匹配的记录(寻找共享关联)