SQL派生表导致未知列

时间:2013-03-11 11:04:48

标签: sql mysql-error-1054 derived-table

+------------------+        +------------------+    
| object           |        | example          |
+------------------+        +------------------+    
| id               |        | id               |    
| table_name       |        | ...              |    
| ref_id           |        |                  |    
+------------------+        +------------------+    

object  [ id = 5, table_name = example, ref_id = 2]
example [ id = 2 ]

我有一个表,它可以表示一组源自许多不同表的对象。 这些对象都有id,由object.ref_id引用。

我试图通过object.table_name选择原始对象(来自object.id引用的表格)。为此,我尝试使用以下SQL查询。虽然这导致#1054 - Unknown column 'entity.id' in 'where clause'

SELECT  * 
FROM    (
        SELECT  table_name
        FROM    object 
        WHERE   id = 5) AS entity
WHERE   entity.id = (
        SELECT  ref_id
        FROM    object 
        WHERE   id = 5)

我做错了什么?

案例

SELECT * 
FROM example 
WHERE id = (
    SELECT  ref_id
    FROM    object 
    WHERE   id = 5 )

虽然,对于我的情况,FROM子句并不像示例中那么容易,因为此值通常来自object.table_name

使用TOMBOM方法更新

使用Tombom的解决方案会导致错误,为了测试我已经替换了CONCAT函数中的变量。

SET @sql = CONCAT('SELECT * FROM ', 'example', ' WHERE id = ', '1');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
  

#1243 - 给予EXECUTE

的未知预处理语句处理程序(stmt)

2 个答案:

答案 0 :(得分:2)

你不能告诉MySQL(子)查询的结果是这样的表名。您必须使用结果构建动态语句。

SELECT @tableName:=table_name, @refId:=ref_id FROM object WHERE id = 5 LIMIT 1;

SET @sql = CONCAT('SELECT * FROM ', @tableName, ' WHERE id = ', @refId);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

更新:请尝试使用存储过程:

DELIMITER $$
CREATE PROCEDURE procName(IN my_id INT)
BEGIN
SELECT @tableName:=table_name, @refId:=ref_id FROM object WHERE id = my_id LIMIT 1;

SET @sql = CONCAT('SELECT * FROM ', @tableName, ' WHERE id = ', @refId);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;

然后使用

执行存储过程
CALL procName(5);

答案 1 :(得分:1)

我最近遇到了完全相同的问题。当我删除最后一行DEALLOCATE PREPARE stmt;时,一切都开始有效了。