有一个表questions
有一列service_table
,其中包含数据库中的另一个表名
我需要在子查询中访问此表名:
SELECT * FROM `questions` AS `q`
WHERE EXISTS
(SELECT *
FROM
`q`.`service_table` AS `ent1`
WHERE ent1.user_id = q.user_id)
运行此查询会导致错误:
表q.service_table不存在
问题表架构:
id user_id service_type service_id title description
------ ------- -------------- ------------ ------ -----------
1 83 translates 1 nana hi there
translates
表(问题相关服务之一)架构:
id user_id context
------ ------- --------------
1 83 something
答案 0 :(得分:2)
我需要在子查询中访问此表名
不可能。
在SQL的所有方言中都有一个明确定义的边界,用于服务器在最初解析查询时必须理解的内容。它们不能“稍后”提供(例如,来自行数据)。对象标识符就是其中之一 - 在检查任何行之前建立模式/表/列名称。
这里有另一种选择,如果它看似粗略,那么这是因为你的设计是非常规的。
SELECT q.*
FROM questions q
WHERE CASE q.service_table
WHEN 'translates'
THEN EXISTS (SELECT * FROM translates x WHERE x.user_id = q.user_id)
WHEN 'typings'
THEN EXISTS (SELECT * FROM typings x WHERE x.user_id = q.user_id)
WHEN 'theses'
THEN EXISTS (SELECT * FROM theses x WHERE x.user_id = q.user_id)
ELSE NULL END;
更正确的设计将是一个表,例如“service”,其中每个服务都有一个id和一个名称以及一个表,例如“user_has_service”,其中包含user_id和service_id,两者都是主键。
然后在“问题”表中,使用service_id。
SELECT *
FROM question q
JOIN user_has_service h
ON h.user_id = q.user_id
AND h.service_id = q.service_id;
更简单,不是吗?这将表现得更好,更易于维护,与关系数据库设计的原则一致,并且您不需要为每个单独的服务单独使用表。
答案 1 :(得分:0)
SELECT q.* FROM questions q
INNER JOIN translates ent1
ON ent1.user_id = q.user_id
注意我不能在查询中使用动态表名。这是不允许的。