【问题标题】:Subquery for fetching table name获取表名的子查询
【发布时间】:2013-06-20 00:53:42
【问题描述】:

我有一个这样的查询:

SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'

基本上,主查询的表名是通过子查询获取的。

我收到一个错误,#1054 - Unknown column 'group' in 'where clause'

当我调查时(去掉 where 子句),我发现查询始终只返回子查询结果。

子查询表adm_linkedfields具有结构id | name | linktable

目前正在使用带有 PDO 的 MySQL,但查询应该与主要数据库兼容(即 Oracle、MSSQL、PgSQL 和 MySQL)

更新: 子查询应返回主查询的表名。在这种情况下,它将返回tbl_company

主查询的表tbl_company 具有以下结构: id | name | group

提前致谢。

【问题讨论】:

  • 查看我的答案以了解错误原因。顺便说一句,“组”列的来源......它不在您的表定义中?它是 DT 而不是 SubQ。
  • 为什么要投反对票?如果有给出的理由,请欣赏。
  • @user2407394 他在 WHERE 子句中调用“组”列,但子查询只返回一个名为链接表的列。
  • @jakub:这是“DT”而不是 subQ。他在我发表评论后更新了这个问题。。@Ravi:感谢更新。现在我明白你想做什么了。我倾向于同意 Jakub 的回答。 -1 是因为缺乏细节。删除它。

标签: mysql sql sql-server oracle postgresql


【解决方案1】:

动态 SQL 不能那样工作,您创建的是一个内联视图,请仔细阅读。更重要的是,您无法创建适用于每个数据库的动态 sql 查询。如果您的链接表数量有限,您可以尝试使用左连接或联合从所有表中进行选择,但如果您没有充分的理由不希望这样做。 只需在一个查询中选择表名,然后再创建另一个以访问正确的表(通过在 php 中创建查询字符串)。

【讨论】:

  • 谢谢雅库布。我就是这么做的。想知道我是否可以在一个查询中完成,而不是拨打两个电话。
【解决方案2】:

这是一个问题:

SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo 
WHERE group='BEST';

您从仅包含一列“linktable”的 DT 中选择,然后您不能将任何其他列放在外部块的 where 子句中。从块的角度考虑,外部选择是指一个仅包含一列的 DT。

当你尝试这样做时,你的问题是相似的:

create table t1(x1 int);
select * from t1 where z1 = 7;  //error

【讨论】:

  • 谢谢。我将表名存储在另一个表中(试图通过子查询获取),并希望从该表中返回所有行。如果可能有帮助,我已经在更新中给出了我的目标表结构。
【解决方案3】:

您的查询是:

SELECT *
FROM (SELECT linktable
      FROM adm_linkedfields
      WHERE name = 'company'
     ) cbo
WHERE group='BEST'

首先,如果您对跨数据库兼容性感兴趣,请不要在 SQL 保留字之后命名列或表。 group 是一个非常非常糟糕的专栏名称。

其次,from 子句返回一个包含名称列表的表(表的名称,但这无关紧要)。没有名为group 的列,所以这就是您遇到的问题。

你能做些什么来解决这个问题?一个天真的解决方案是运行子查询,运行它,然后在动态语句中使用生成的表名来执行您想要的查询。

根本问题是您的数据结构。拥有多个具有相同结构的表通常是设计不佳的标志。你基本上有两个选择。

一个。如果您可以控制数据库结构,请将所有数据放在一个表中,例如linktable。这将包含所有公司的信息,以及group(或您重命名的任何名称)的列。此解决方案兼容所有数据库。如果表中有大量数据(想想数千万行),那么出于性能原因,您可能会考虑对数据进行分区。

两个。如果您无法控制数据,请创建一个将所有表连接在一起的视图。比如:

create view vw_linktable as
    select 'table1' as which, t.* from table1 t union all
    select 'table2', t.* from table2 t

这也兼容所有数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多