来自不同数据库的MariaDB JOIN表基于列值

时间:2018-01-02 13:55:30

标签: mysql mariadb

如何将列值作为数据库名称使用来自这两个不同数据库的两个表的JOIN

我已经使用静态定义的(第二个)数据库名称在两个数据库之间成功连接了两个表:

SELECT * 
FROM db1.table_a AS ta
INNER JOIN db2.table_b AS tb on (ta.db_table_name = b.user_id) 

然而,db2.table_b在该查询中,我需要以某种方式使db2成为第一个数据库中第一个表的值; 表名将被静态定义。所有相关的线程都完全没用,而且非常复杂。

详细信息:有一个通用数据库,所有其他数据库代表相同的应用程序,但适用于不同的帐户。为了使所有不同帐户上的所有用户能够彼此交互(例如database_2.accounts.user.43(DB-> Table-> Column-> ID(43)),数据库(上面的db1)不仅要存储用户的id,还要存储必须连接的数据库的名称。

帮助可视化事物:

  • 数据库:常见
  • 数据库:db2
SELECT id, database_name 
FROM common.table_a AS ct 
INNER JOIN [database_name].table_b AS dn ON (ct.user_id = [database_name].users.id)

视觉上返回的数据应如下所示:

+----------+------------+----------+
| database | account_id | username |
+----------+------------+----------+
| db1      | 1          | John     |
+----------+------------+----------+
| db2      | 1          | Sally    |
+----------+------------+----------+
| db3      | 43         | John     |
+----------+------------+----------+
| db4      | 1          | Sally    |
+----------+------------+----------+

然后HTML输出应该如下所示:

  • 来自db1的John的评论。
  • 来自Sally的评论来自db2。
  • 来自db3的John的评论。
  • 来自Sally的评论来自db4。

我可以担心从视觉上确保来自db3的John和来自db3的John(以及来自db2的Sally和来自db4的Sally)所有这四个人在现实生活中都是不同的人。根据包含要用于JOIN的数据库名称的列值来选择它们的动态方面是最重要的。

2 个答案:

答案 0 :(得分:0)

所有条件都相同(我敢打赌它们不是)并假设所有模式/ dbs都在同一台服务器上,你应该能够构造一个简单的动态sql语句。

所以给出

+----+------+
| id | name |
+----+------+
|  1 | aaa  |
|  2 | bbb  |
+----+------+
2 rows in set (0.00 sec)

其中name作为db name的代理,我们可以先选择所有不同的名称,然后创建一个sql语句,将所有dbs中的所有表联合起来。这样的事情。

SET @SQL =
( 
SELECT  GROUP_CONCAT(GCSTRING)
FROM
(
SELECT 'A' AS GC,CONCAT('SELECT ID,NAME FROM USERS U1 ',JSTRING,' ',DBNAME,' AS  ',NAMEALIAS,'  ON ',NAMEPREFIX,'.',USTRING) GCSTRING
FROM
(
SELECT DISTINCT 'JOIN ' AS JSTRING,NAME DBNAME , 
        NAME AS NAMEALIAS, NAME AS NAMEPREFIX, 'TABLEB.USER_ID = UI.NAME UNION' USTRING 
FROM USERS
) S
) T
GROUP BY GC
)
;

SET @SQL = REPLACE(@SQL,',',' ');
SET @SQL = SUBSTRING(@SQL,1,LENGTH(@SQL) - 5);
SET @SQL = CONCAT(@SQL,';');
SELECT @SQL

+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| @SQL                                                                                                                                                                    |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| SELECT ID NAME FROM USERS U1 JOIN  aaa AS  aaa  ON aaa.TABLEB.USER_ID = UI.NAME UNION SELECT ID NAME FROM USERS U1 JOIN  bbb AS  bbb  ON bbb.TABLEB.USER_ID = UI.NAME ; |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

答案 1 :(得分:0)

你有数百个数据库吗?这将是一个“糟糕”的事情。设计。为了进一步讨论,请解释为什么你有这么多。

如果你没有很多数据库,但你需要动态选择哪个数据库,再次设计不佳;让我们进一步讨论。

如果您必须执行其中一项,则将其隐藏在存储例程中(如P.Salmon几乎建议;他的代码需要一些抛光)或应用程序库(PHP,Java,无论如何)。

否则,无论您在哪里说table_a,都可以将其替换为db1.table_a。事实上,您可以看到MySQl这样做:EXPLAIN EXTENDED SELECT ...; SHOW WARNINGS;示例:

mysql> EXPLAIN EXTENDED SELECT province FROM canada; SHOW WARNINGS;
+----+-------------+--------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table  | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+-------+---------------+----------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | canada | index | NULL          | province | 105     | NULL | 5484 |   100.00 | Using index |
+----+-------------+--------+-------+---------------+----------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

+-------+------+---------------------------------------------------------------------------------------+
| Level | Code | Message                                                                               |
+-------+------+---------------------------------------------------------------------------------------+
| Note  | 1003 | /* select#1 */ select `world`.`canada`.`province` AS `province` from `world`.`canada` |
+-------+------+---------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

在此示例中,表canada已替换为world.canada,因为world是数据库。