我正在开发一个电子学习项目,其中有一个名为chapter的表,其中有一个名为question_table的列,这是一个表,其中添加了特定章节的问题。
现在的问题是我想显示所有章节中的所有问题,我使用以下sql查询
SELECT * FROM (SELECT `question_table` FROM `chapter`)
但它不起作用并给出错误:
“每个派生表都必须有自己的别名”。
注意:我想使用SQL而不是PHP。
答案 0 :(得分:0)
此处的派生表是(SELECT ...)
的结果。你需要给它一个别名,如下:
SELECT * FROM (SELECT question_table FROM chapter) X;
修改,重新动态表格
如果你事先知道所有表格,你可以将它们结合起来,即:
SELECT * FROM
(
SELECT Col1, Col2, ...
FROM Chapter1
UNION
SELECT Col1, Col2, ...
FROM Chapter2
UNION
...
) X;
要一般性地执行此解决方案,您需要使用dynamic sql来实现目标。
一般情况下,这表示您的表格设计中有气味 - 您的章节数据应该在一个表格中,例如按章节分类。
如果出于规模或性能原因需要对数据进行分片,则执行此操作的典型机制是跨多个数据库,而不是同一数据库中的表。 MySql可以处理每个表的大量行,如果表被正确编入索引,性能将不会成为问题。
答案 1 :(得分:0)
在MySQL中,您必须为每个子查询(“派生表”)提供别名:
SELECT * FROM (SELECT question_table FROM chapter) t --notice the alias "t"
答案 2 :(得分:0)
首先,我认为您最好重新设计数据库。具有相同数据的相同结构的多个表通常不是一个好主意。
然而,您需要的是使用MySQL过程来构建一些动态SQL,然后执行它,返回结果数据。
可以使用以下程序执行此操作: -
DROP PROCEDURE IF EXISTS dynamic;
delimiter //
CREATE PROCEDURE dynamic()
BEGIN
DECLARE question_table_value VARCHAR(25);
DECLARE b INT DEFAULT 0;
DECLARE c TEXT DEFAULT '';
DECLARE cur1 CURSOR FOR SELECT `question_table` FROM `chapter`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1;
OPEN cur1;
SET b = 0;
WHILE b = 0 DO
FETCH cur1 INTO question_table_value;
IF b = 0 THEN
IF c = '' THEN
SET c = CONCAT('SELECT * FROM `',question_table_value, '`');
ELSE
SET c = CONCAT(c, ' UNION SELECT * FROM `',question_table_value, '`');
END IF;
END IF;
END WHILE;
CLOSE cur1;
SET @stmt1 := c;
PREPARE stmt FROM @stmt1;
EXECUTE stmt;
END
这是创建一个名为dynamic的过程。这不需要参数。它设置一个游标来读取章节表中的question_table列值。它查看结果,构建一个包含SQL的字符串,这是一个来自每个表的SELECT,其结果是UNIONed。然后进行PREPAREd并执行。该过程将从默认执行的SQL返回结果集。
您可以使用以下命令调用此方法返回结果: -
CALL dynamic()
缺点是,如果没有要返回的行,这不会给出好的结果,并且它们不容易维护或使用开发人员的常规工具进行调试。除此之外,很少有人拥有任何真正的存储过程技能来维护它。