2012-10-02 74 views
10

我都第一個數據庫(DBA)有這樣的表,命名爲用戶名如何在2個不同的數據庫上左連接2個表?

+------------------+--------------+ 
| Username   | PhoneNumber | 
+------------------+--------------+ 
| jamesbond007  | 555-0074  | 
| batmanbegins  | 555-0392  | 
+------------------+--------------+ 

然後,在另一邊,我有DBB與表這樣的,命名爲PrivateMessage

+------------------+---------------------------------+ 
| Username   | Message       | 
+------------------+---------------------------------+ 
| jamesbond007  | I need new bond-girl   | 
| batmanbegins  | thanks for the paycheck, Nolan | 
+------------------+---------------------------------+ 

現在,如何這兩個表從2個不同的數據庫結合,從而輸出將是這樣的:

+------------------+--------------+---------------------------------+ 
| Username   | PhoneNumber | Message       | 
+------------------+--------------+---------------------------------+ 
| jamesbond007  | 555-0074  | I need new bond-girl   | 
| batmanbegins  | 555-0392  | thanks for the paycheck, Nolan | 
+------------------+--------------+---------------------------------+ 
+0

既然你有不同的排序規則,見我的回答如下。 –

+1

dbA,dbB是一個表而不是數據庫。 – fearis

回答

10

您可以簡單地加入不同數據庫的表。您需要在FROM子句中指定數據庫名稱。爲了使它更短,加上它的ALIAS

SELECT a.*,   -- this will display all columns of dba.`UserName` 
     b.`Message` 
FROM dba.`UserName` a -- or LEFT JOIN to show all rows whether it exists or not 
     INNER JOIN dbB.`PrivateMessage` b  
     ON a.`username` = b.`username` 

但一些如何,有possiblities其中,在username不會有消息。在這種情況下,如果您仍想顯示dba.Username的所有記錄,請使用LEFT JOIN

從您的意見閱讀,表格有不同collation。圍繞這一工作是指定在加入語句COLLATE

SELECT a.*,   -- this will display all columns of dba.`UserName` 
     b.`Message` 
FROM dba.`UserName` COLLATE latin1_swedish_ci a 
     LEFT JOIN dbB.`PrivateMessage` COLLATE latin1_swedish_ci b  
     ON a.`username` = b.`username` 

你可以改變latin1_swedish_ci到任何你想要的。

有關整理的詳細信息,請參閱

Character Sets and Collations in MySQL


這個名單如果你有足夠的權限ALTER表,只需使用這個語法來手動轉換並符合他們的排序規則,

ALTER TABLE tbl_name CONVERT TO CHARACTER SET latin2 COLLATE 'latin2_general_ci'; 
+2

你是對的。我在桌子上有不同的校對。現在修復... –

+0

太棒了!你的問題已經解決了? –

+1

是的。感謝你......標記爲「答案」,併爲你+1 ... –

0

這個SQL很容易...

SELECT A.Username, A.PhoneNumber, B.Message 
FROM dbA.Username as A 
INNER JOIN dbB.PrivateMessage as B ON A.Username = B.Username 

...假設您可以在您的連接中訪問這兩個數據庫。

如果你不能訪問它們,你必須使用不同的方法(比如在查詢之前將一個表複製到另一個數據庫或類似的東西)。

+0

我從您的代碼中獲得了此錯誤消息:#1267 - 非法混合排序規則(utf8_unicode_ci,IMPLICIT)和(utf8_general_ci,IMPLICIT)進行操作'=' –

+0

然後,您的表格有不同的排序規則,所以你不能加入它們。爲了執行這個查詢,你首先必須執行它們,一種方法是將'ALTER TABLE dbA.Username CONVERT TO CHARACTER SET uft8 COLLATE utf8_general_ci; ALTER TABLE dbB.PrivateMessage CONVERT TO CHARACTER SET uft8 COLLATE utf8_general_ci;'。請記住,這改變了表格的字符集,所以只有在你a)知道你在做什麼以及b)它是否不影響其他關鍵應用程序時,請做到這一點。 – Bjoern

3

就像您一個普通的表,除了指定的數據庫:

SELECT dbA.Username, dbA.PhoneNumber, dbB.Message 
    FROM dbA.Username LEFT JOIN dbB.PrivateMessage 
    ON (dbA.UserName.Username = dbB.PrivateMessage.Username); 

事情看出來:

  • LEFT JOIN將返回所有用戶,也包括那些沒有消息(使用INNER JOIN檢索僅用戶郵件)
  • 具有多個郵件的用戶將出現多次(使用聚合和GROUP BY只檢索每個用戶發一條消息 - 你必須提供一個標準來選擇一個消息)
  • 您需要在兩個數據庫(否​​則一些用戶與權限上既有複製,例如查詢權限定期在crontab中,一個表或表從數據庫到其他的子集)
  • 排序規則可能不匹配。如果是這種情況,則必須改變使用這兩個表中的一個核對任COLLATE或一個DB的場與CONVERT轉換爲其他的字符集:CONVERT(db.table.field USING Latin1的),這將防止使用索引從而降低性能。您可以修改這兩個表中的一個,但驗證,你不破壞任何查詢或應用程序正在使用ALTER「編表(在緊要關頭,整個數據庫轉換爲久經鍛鍊UTF8)。
  • JOIN即使您在兩個表中都有INDEX,對文本字段的效率也不是很高,最好讓消息表保存唯一的數字用戶標識來引用消息所有者。我知道具有不同邏輯的兩個不同數據庫可能不利於此解決方案,但您可以應用上述「技巧」之一(「複製表或其子集」),並定期導出已轉換的ID和「編輯表從數據庫到另一個。那個定期的查詢將會很昂貴,但所有後續的JOIN都會大大受益。

試運行

這將創建兩個不同數據庫的結構相同的兩個表,然後將它們同時在第三數據庫。

Welcome to the MySQL monitor. Commands end with ; or \g. 
Your MySQL connection id is 3 
Server version: 5.6.30 openSUSE package 

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 

Oracle is a registered trademark of Oracle Corporation and/or its 
affiliates. Other names may be trademarks of their respective 
owners. 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 

mysql> CREATE DATABASE first_database; 
Query OK, 1 row affected (0.01 sec) 

mysql> CREATE DATABASE second_database; 
Query OK, 1 row affected (0.00 sec) 

mysql> USE first_database; 
Database changed 
mysql> CREATE TABLE mytable (x integer, t varchar(32)); 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO mytable (x, t) VALUES (1, 'One in First Database'), (2, 'Two in First Database'); 
Query OK, 2 rows affected (0.00 sec) 
Records: 2 Duplicates: 0 Warnings: 0 

mysql> USE second_database; 
Database changed 
mysql> CREATE TABLE mytable (x integer, t varchar(32)); 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO mytable (x, t) VALUES (1, 'One in Second Database'), (3, 'Three in Second Database'); 
Query OK, 2 rows affected (0.00 sec) 
Records: 2 Duplicates: 0 Warnings: 0 

mysql> USE test; 
Database changed 
mysql> SELECT * FROM first_database.mytable LEFT JOIN second_database.mytable USING (x); 
+------+-----------------------+------------------------+ 
| x | t      | t      | 
+------+-----------------------+------------------------+ 
| 1 | One in First Database | One in Second Database | 
| 2 | Two in First Database | NULL     | 
+------+-----------------------+------------------------+ 
2 rows in set (0.00 sec) 

mysql> 
+1

我得到了這個錯誤信息:#1267 - 非法混合排序(utf8_unicode_ci,IMPLICIT)和(utf8_general_ci,IMPLICIT)進行操作'=' –

+0

我得到的錯誤與@Robert Hanson相同。你明白了@Robert? – jason3w

+0

這將在同一個數據庫中聯合使用兩張表 – fearis

0

試試下面的代碼

SELECT * FROM dbA.Username JOIN dbB.PrivateMessage USING(Username); 
相關問題