从所有表中选择所有记录,每个派生表必须具有自己的别名

时间:2014-10-17 06:18:36

标签: sql database mysqli

我正在开发一个电子学习项目,其中有一个名为chapter的表,其中有一个名为question_table的列,这是一个表,其中添加了特定章节的问题。

现在的问题是我想显示所有章节中的所有问题,我使用以下sql查询

  SELECT * FROM (SELECT `question_table` FROM `chapter`)

但它不起作用并给出错误:

  

“每个派生表都必须有自己的别名”。

注意:我想使用SQL而不是PHP。

3 个答案:

答案 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;

SqlFiddle here

要一般性地执行此解决方案,您需要使用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()

缺点是,如果没有要返回的行,这不会给出好的结果,并且它们不容易维护或使用开发人员的常规工具进行调试。除此之外,很少有人拥有任何真正的存储过程技能来维护它。