[英]MariaDB JOIN tables from different databases based on column value
如何使用列值作為數據庫名稱來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.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輸出應如下所示:
我可以擔心從視覺上確保db1中的John和db3中的John(以及db2中的Sally和db4中的Sally)在現實生活中都是四個不同的人。 這是基於包含包含要用於JOIN的數據庫名稱的列值的值選擇它們的動態方面。
所有事物都是平等的(我敢打賭它們不是),並且假設所有模式/數據庫都在同一服務器上,那么您應該能夠構造一個簡單的動態sql語句。
所以給
+----+------+
| id | name |
+----+------+
| 1 | aaa |
| 2 | bbb |
+----+------+
2 rows in set (0.00 sec)
在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)
您有數百個數據庫嗎? 那將是一個“糟糕”的設計。 要進一步討論,請解釋為什么會有這么多。
如果您沒有很多數據庫,但是您需要動態地選擇哪個數據庫,那又是糟糕的設計; 讓我們進一步討論。
如果您必須執行其中一項操作,則將其隱藏在“存儲的例程”中(正如P.Salmon幾乎建議的那樣;他的代碼需要完善)或在應用程序庫(PHP,Java等)中隱藏。
否則,無論您在何處說table_a
,都可以將其替換為db1.table_a
。 實際上,您可以看到MySQl正在這樣做: EXPLAIN EXTENDED SELECT ...; SHOW WARNINGS;
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
是數據庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.