2012-10-02 47 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); 
相关问题