簡體   English   中英

基於列值的來自不同數據庫的MariaDB JOIN表

[英]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,而且還必須存儲必須連接的數據庫的名稱。

為了幫助可視化事物:

  • 數據庫:通用
  • 數據庫: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的評論。
  • 來自db2的Sally的評論。
  • db3中John的評論。
  • 來自db4的Sally的評論。

我可以擔心從視覺上確保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)

在此示例中,表canadaworld.canada代替,因為world是數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM