Mysql 如何在两个不同的数据库上左键联接两个表?
我有第一个数据库(dbA),它的表是这样的,名为Username:Mysql 如何在两个不同的数据库上左键联接两个表?,mysql,sql,Mysql,Sql,我有第一个数据库(dbA),它的表是这样的,名为Username: +------------------+--------------+ | Username | PhoneNumber | +------------------+--------------+ | jamesbond007 | 555-0074 | | batmanbegins | 555-0392 | +------------------+--------------+
+------------------+--------------+
| Username | PhoneNumber |
+------------------+--------------+
| jamesbond007 | 555-0074 |
| batmanbegins | 555-0392 |
+------------------+--------------+
+------------------+---------------------------------+
| Username | Message |
+------------------+---------------------------------+
| jamesbond007 | I need new bond-girl |
| batmanbegins | thanks for the paycheck, Nolan |
+------------------+---------------------------------+
然后,在另一边,我有dbB和这样的表,名为PrivateMessage:
+------------------+--------------+
| Username | PhoneNumber |
+------------------+--------------+
| jamesbond007 | 555-0074 |
| batmanbegins | 555-0392 |
+------------------+--------------+
+------------------+---------------------------------+
| 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 |
+------------------+--------------+---------------------------------+
您可以简单地连接不同数据库的表。您需要在
FROM
子句中指定数据库名称。要使其更短,请在其上添加一个别名
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`
但是有些情况下,用户名中可能没有消息。在这种情况下,如果仍要显示dba.Username
的所有记录,请使用LEFT JOIN
从您的注释中可以看出,这些表具有不同的排序规则。解决这一问题的方法是在连接的语句上指定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\u swedish\u ci
更改为您想要的任何内容
有关排序规则的更多信息,请参阅以下完整列表:
如果您有足够的权限更改表,只需使用此语法手动转换和匹配它们的排序规则
ALTER TABLE tbl_name CONVERT TO CHARACTER SET latin2 COLLATE 'latin2_general_ci';
这方面的SQL非常简单
SELECT A.Username, A.PhoneNumber, B.Message
FROM dbA.Username as A
INNER JOIN dbB.PrivateMessage as B ON A.Username = B.Username
…假设您可以访问连接中的两个数据库
如果无法访问它们,则必须采用不同的方法(如在查询之前将一个表复制到另一个数据库或类似的方法)。与普通表相同,但指定数据库除外:
SELECT dbA.Username, dbA.PhoneNumber, dbB.Message
FROM dbA.Username LEFT JOIN dbB.PrivateMessage
ON (dbA.UserName.Username = dbB.PrivateMessage.Username);
注意事项:
- LEFT JOIN将返回所有用户,也返回那些没有消息的用户(使用
内部连接
仅检索有消息的用户)
- 具有多条消息的用户将出现多次(使用聚合和
groupby
仅检索每个用户的一条消息-您必须提供选择一条消息的标准)
- 您需要在两个数据库上都具有查询权限(否则,在两个数据库上都具有权限的某些用户必须将一个表或表的子集从一个数据库定期复制到另一个数据库,例如,在crontab中)
- 排序规则可能不匹配。如果是这种情况,您必须使用CONVERT(DB.table.field使用拉丁语1)或将一个DB的字段转换为另一个DB的字符集来更改两个表中的一个表的排序规则,这将阻止使用索引,从而降低性能。您可以修改这两个表中的一个,但是验证您没有中断正在使用
ALTER
“ed”表的任何查询或应用程序(必要时,将整个数据库转换为经过良好处理的UTF8)
JOIN
s在文本字段上的效率不是很高,即使在这两个表中都有索引;最好让消息表包含一个唯一的数字userid来引用消息所有者。我知道两个不同的数据库具有不同的逻辑可能不利于此解决方案,但您可以应用上述“技巧”(“复制表或其子集”)中的一个,并定期将转换和标识的表从数据库导出到另一个数据库。一个周期性的查询将是昂贵的,但所有后续的连接都将受益匪浅
试运行
这将在两个不同的数据库中创建具有相同结构的两个表,并在第三个数据库中连接它们
请尝试下面的代码
SELECT * FROM dbA.Username JOIN dbB.PrivateMessage USING(Username);
我收到了这个错误消息:#1267-操作“=”的排序规则(utf8_unicode_ci,隐式)和(utf8_general_ci,隐式)的非法混合,我得到了与@Robert Hanson相同的错误。你弄明白了吗@Robert?这将连接同一数据库中的两个表否,@fearis-它将dbA中的一个表连接到dbB中的一个表,dbA和dbB是两个不同的数据库。如果您尝试了此操作,但没有成功,您可以问一个问题(或添加注释以指定在我的示例中不起作用的内容)。我从您的代码中得到以下错误消息:#1267-非法混合排序规则(utf8_unicode_ci,隐式)和操作“=”的(utf8_general_ci,隐式),那么您的表具有不同的排序规则,因此无法将它们合并。为了执行此查询,首先必须将它们均匀化,一种方法是更改表dbA.Username转换为字符集uft8 COLLATE utf8\u general\u ci;ALTER TABLE dbB.PRIVATEMSAGE转换为字符集uft8 COLLATE utf8\u general\u ci代码>。请记住,这会更改表的字符集,因此,只有当您a)知道自己在做什么,b)不影响其他关键应用程序时,才可以这样做。因为您有不同的排序规则,请参阅下面的答案。dbA,dbB是表而不是数据库。上面的答案是将表连接到同一数据库中。不能轻易地从不同的位置连接两个表databases@fearis不,上面的答案是连接两个不同数据库中的两个表:dba.UserName
和dbB.PrivateMessage
dba
和dbB
是数据库,UserName
和PrivateMessage
是两个表(顺便说一句,来自不同的数据库)。然而,上面的答案只适用于同一服务器上的数据库