如何在2个不同的数据库上连接2个表?

时间:2012-10-02 05:56:00

标签: mysql sql

我的第一个数据库(dbA)包含这样的表,名为用户名

+------------------+--------------+
| 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  |
+------------------+--------------+---------------------------------+

4 个答案:

答案 0 :(得分:14)

您可以简单地加入不同数据库的表。您需要在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`

但有些方面,username中有可能存在消息的可能性。在这种情况下,如果您仍想显示LEFT JOIN的所有记录,请使用dba.Username

从您的评论中读取,这些表格具有不同的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更改为您想要的任何内容。

有关COLLATION的更多信息,请参阅

的完整列表

<强> Character Sets and Collations in MySQL


如果您有足够的ALTER表格权限,只需使用此语法手动转换和匹配其排序规则,

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

答案 1 :(得分: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更改两个表中的一个表的排序规则,或者使用CONVERT将一个数据库的字段转换为另一个数据库的字符集:CONVERT(db.table。字段使用Latin1),将阻止使用索引从而降低性能。您可以修改两个表中的一个,但是验证您不会破坏使用ALTER'ed表的任何查询或应用程序(在紧要关头,将整个数据库转换为-tempered UTF8)。
  • 即使你在两个表中都有INDEX,文本字段上的
  • JOIN也不是很有效;最好让Message表包含唯一的数字 userid 来引用消息所有者。我知道具有不同逻辑的两个不同数据库可能不利于此解决方案,但您可以应用上述“技巧”之一(“复制表或其子集”)并定期导出,从DB到另一个的转换和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>

答案 2 :(得分: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

...假设您可以访问连接中的两个数据库。

如果您无法访问它们,则必须采用不同的方法(例如在查询之前将一个表复制到另一个数据库或类似的方法)。

答案 3 :(得分:0)

尝试以下代码

SELECT * FROM dbA.Username JOIN dbB.PrivateMessage USING(Username);