【问题标题】:Join all prefixed tables into one将所有带前缀的表合并为一个
【发布时间】:2019-01-16 14:09:54
【问题描述】:

我有多个表,即jibs3_postsjibs4_postsjibs5_posts.. 等等。有什么方法可以使用jibs-前缀的某种通配符在所有这些表之间建立连接?

例如:

SELECT * FROM 'jibs*_posts';

附:抱歉,如果这是重复的,但找不到任何解决方案。

P.P.S 这是一个 WordPress 多站点

【问题讨论】:

  • 没有。您可以通过一个表 jibs_posts 来修复您的数据模型,该表将这些子表中的数据组合在一起。
  • 你为什么有这么多桌子?一个普通的 jibs_post 表不是更好吗?
  • @jarlh Wordpress 多站点网络似乎造成了这种混乱
  • @RiggsFolly 可能接手了一个 WP 项目,最后一次更新是 2008 年...

标签: mysql sql wordpress


【解决方案1】:

另一种选择。如果没有太频繁地添加新的jibs 表,您可以创建一个将所有UNIONs 放在一起的视图,然后针对该视图编写查询。这样一来,您只需进行一次繁琐的输入即可。

如果记忆有用(我已经有一段时间没有在 Wordpress 网站上玩过了),您应该能够将必要的对象添加到数据库中。

大意是:

CREATE VIEW v_jibs_posts AS
  SELECT <column_list> FROM jibs1_posts
  UNION
  ...<SELECTS from all the tables>
  UNION
  SELECT <column_list> FROM jibs<n>_posts

然后,当应用程序创建新表时,只需在视图中添加一个额外的 UNION

当然,如果它们经常弹出,维护起来就太麻烦了。

编辑:如果您想变得花哨,可以使用 Eray Balkanli 的动态 SQL 生成 ALTER VIEW 语句来获取新表,然后安排它定期运行。

【讨论】:

  • 不幸的是,它们会被频繁添加,所以维护起来太难了
  • 当您评论时我正在输入一个编辑,这可以减轻一些维护痛苦,这取决于您通过查询更新之间的视图对可能丢失数据的容忍度。
【解决方案2】:

你可以这样做

SHOW TABLES LIKE 'jibs%_posts';

这将列出所有具有该命名方案的表。

然后您可以使用UNION 连接所有表(如果它们具有相同的列数)

SELECT * FROM jibs_posts
UNION
// ... more SELECTS
UNION
SELECT * FROM jibsX_posts;

【讨论】:

  • 这可能很难维护,因为会频繁添加更多表
【解决方案3】:

这在 SQL 中是不可能的,但有其他方法。

如果有充分的理由放弃多个表(即,如果数据模型可以满足一个通用表),您可以进行从多个表到单个表的一次性转换。

如果有充分的理由保留多个表(即,如果您的数据模型或某些逻辑约束决定了这种安排),那么这是组合工具的好情况。具体来说,您可以使用自己喜欢的编程或脚本语言来生成引用所有表的 SQL,然后使用生成的 SQL。

许多编程语言都允许您生成 SQL 并通过数据库绑定在同一个程序中使用它。

编辑:我看到您已经添加了wordpress 标记(我在答案出现之前就开始撰写答案),所以我不确定我的答案在多大程度上适用。也就是说,我不确定你有多少访问权限才能直接与数据库交互。如果您受限于 Wordpress 的要求和/或 Wordpress 允许您运行您想要运行的 SQL 的方式,那么我的通用 MySQL / SQL 答案可能没有多大帮助。

不过,我的一般建议是使用工具箱中的所有工具来解决问题,并考虑综合优势的方法,因为 SQL 不支持表名的通配符。

【讨论】:

  • 我确实可以访问数据库,但目前这样的重构太大了
【解决方案4】:

1- 获取您的表名:

declare @row_number int = 0;

CREATE TEMPORARY TABLE JibsTables (table_name varchar(50), num int)

INSERT INTO JibsTables (table_name, num)
SELECT table_name, (@row_number:=@row_number + 1) AS num
FROM information_schema.tables 
WHERE table_schema='your_database_name'
  AND table_name like 'jibs%'

2- 循环创建动态查询。

declare @counter = 1
declare @sql nvarchar(max);
declare @temptable nvarchar(100);
declare @limit int = (select count(*) from JibsTables)

while @counter <= @limit
begin
   set @temptable = select table_name from JibsTables where num = @counter

   if @counter <> @limit
   begin
      set @sql = @sql + ' select * from ' + @temptable + ' union'
   end
   else
   begin
      set @sql = @sql + ' select * from ' + @temptable + ';'
   end

   set @counter = @counter + 1
end

3- 执行你的动态查询

PREPARE stmt1 FROM @sql
EXECUTE stmt1
DEALLOCATE PREPARE stmt1;

我熟悉 MSSQL 语法,尽力为 mysql 找到正确的语法,但我相信逻辑很清楚。希望一切都好,请告诉我。

【讨论】:

  • 我无法使用第一个查询从我的数据库中接收表名。临时表 JibsTables 返回空
  • 应该是百分比 % 而不是星号 *
  • @Jesper 你现在可以再试一次吗?确保选择查询返回结果集
  • 最好使用'jibs%posts'作为模板。
猜你喜欢
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多