如何将列值作为数据库名称使用来自这两个不同数据库的两个表的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,还要存储必须连接的数据库的名称。
帮助可视化事物:
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输出应该如下所示:
我可以担心从视觉上确保来自db3的John和来自db3的John(以及来自db2的Sally和来自db4的Sally)所有这四个人在现实生活中都是不同的人。根据包含要用于JOIN的数据库名称的列值来选择它们的动态方面是最重要的。
答案 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
是数据库。