似乎MySQL View 将无法使用准备好的语句或存储过程。
构建查询字符串方法
您可以使用两个查询,其中一个提供员工列表,第二个提供动态生成的表 B。
获取您的员工名单:
SELECT staff FROM A GROUP BY staff
制作字符串
然后循环遍历每个员工并为每个员工生成这个字符串:
(SELECT sum(A2.time) FROM A as A2 WHERE date=A1.date AND staff="<staff>") AS <staff>,
查询
然后生成了这个字符串,在这个查询中使用它:
SELECT A1.date,
<insert-generated-query-string-of-staff>
sum(time)
FROM A as A1 GROUP BY date;
这可能看起来像这样生成的:
SELECT A1.date,
(SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="John") AS John,
(SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="Jeff") AS Jeff,
(SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="James") AS James,
SUM(A1.time)
FROM A as A1 GROUP BY date;
准备好的语句方法
除了您通过 MySQL 而不是您的程序构建查询字符串之外,与之前的方法类似。每次要生成表数据时都需要执行这些操作。
SELECT GROUP_CONCAT( DISTINCT CONCAT(
"(SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff=\"",
staff,
"\") AS ",
staff
) ) INTO @staff from A;
SET @table_b = CONCAT(
'SELECT A1.date, ',
@staff,
', SUM(A1.time) FROM A as A1 GROUP BY date'
);
PREPARE tableB from @table_b;
EXECUTE tableB;
存储过程方法
我遇到了一些其他想法,主要是通过准备好的语句示例
和/或存储过程,并提出了这个过程。
我认为这个更好,因为您不必重新创建查询
准备好的语句。
制作程序:
DROP PROCEDURE generate_table_B;
DELIMITER //
CREATE PROCEDURE generate_table_B()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE staff_name VARCHAR(50) DEFAULT NULL;
DECLARE staff_list CURSOR FOR SELECT staff FROM A GROUP BY staff;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN staff_list;
SET @staff_stmts = '';
get_id: LOOP
FETCH staff_list INTO staff_name;
IF done = 1 THEN
LEAVE get_id;
END IF;
SET @staff_stmts = CONCAT(@staff_stmts, ' (SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="', staff_name,'") AS ', staff_name,',');
END LOOP get_id;
CLOSE staff_list;
SET @table = CONCAT('SELECT A1.date, ', @staff_stmts, ' SUM(A1.time) FROM A as A1 GROUP BY date');
-- verifying the @table string generated
-- select @table;
PREPARE stmt FROM @table;
-- run @table
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
在程序/脚本中调用的语句:
call generate_table_B();
别名
这些是在列名、计算、查询或表之后指定的。
在其中之一之后使用AS 是可选的。
原因是嵌套查询。在这种情况下,如果我们不使用
内部查询的别名将根据其查询与数据进行比较
从外部查询。根据情况,这可能是所需的
结果。但是,下面的查询表明这不是我们想要的。
> SELECT date,
-> (SELECT SUM(time) FROM A WHERE date=date AND staff="John") AS John,
-> (SELECT SUM(time) FROM A WHERE date=date AND staff="Jeff") AS Jeff,
-> (SELECT SUM(time) FROM A WHERE date=date AND staff="James") AS James,
-> SUM(time)
-> FROM A GROUP BY date;
+------+------+------+-------+-----------+
| date | John | Jeff | James | SUM(time) |
+------+------+------+-------+-----------+
| 1 | 9 | 8 | 4 | 10 |
| 2 | 9 | 8 | 4 | 11 |
+------+------+------+-------+-----------+
2 rows in set (0.01 sec)
现在您可能会注意到SUM(time) 列。这有资格作为
计算,所以我们可以为这个列设置一个别名,这样使用起来更友好
选择它时。像这样:
> SELECT date,
-> (SELECT SUM(time) FROM A WHERE date=date AND staff="John") AS John,
-> (SELECT SUM(time) FROM A WHERE date=date AND staff="Jeff") AS Jeff,
-> (SELECT SUM(time) FROM A WHERE date=date AND staff="James") AS James,
-> SUM(time) SummedTime
-> FROM A GROUP BY date;
+------+------+------+-------+------------+
| date | John | Jeff | James | SummedTime |
+------+------+------+-------+------------+
| 1 | 9 | 8 | 4 | 10 |
| 2 | 9 | 8 | 4 | 11 |
+------+------+------+-------+------------+
2 rows in set (0.01 sec)
所有 3 种方法的输出:
+------+-------+------+------+--------------+
| date | James | jeff | john | SUM(A1.time) |
+------+-------+------+------+--------------+
| 1 | 2 | 3 | 5 | 10 |
| 2 | 2 | 5 | 4 | 11 |
+------+-------+------+------+--------------+
2 rows in set (0.00 sec)
MySQL 表和数据:
> show create table A\G
*************************** 1. row ***************************
Table: A
Create Table: CREATE TABLE `A` (
`date` int(11) DEFAULT NULL,
`staff` varchar(50) DEFAULT NULL,
`tp` varchar(50) DEFAULT NULL,
`time` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
> SELECT * FROM A;
+------+-------+-------+------+
| date | staff | tp | time |
+------+-------+-------+------+
| 1 | john | bus | 3 |
| 1 | jeff | car | 3 |
| 1 | James | Train | 2 |
| 2 | Jeff | bus | 5 |
| 2 | john | car | 4 |
| 2 | james | train | 2 |
| 1 | john | train | 2 |
+------+-------+-------+------+
7 rows in set (0.00 sec)
来源: