17

Usernameという名前の、このようなテーブルを持つ最初のデータベース(dbA)があります。

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

次に、反対側に、PrivateMessageという名前のこのようなテーブルを持つdbBがあります。

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

次に、2 つの異なるデータベースからこの 2 つのテーブルを結合して、出力が次のようになるようにする方法を示します。

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

4 に答える 4

17

別のデータベースのテーブルに参加するだけです。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ます。

照合の詳細については、この完全なリストを参照してください。

MySQLの文字セットと照合


テーブルに対して十分な権限がALTERある場合は、この構文を使用して、手動でそれらの照合を変換して照合します。

ALTER TABLE tbl_name CONVERT TO CHARACTER SET latin2 COLLATE 'latin2_general_ci';
于 2012-10-02T06:00:22.653 に答える
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ユーザーごとに 1 つのメッセージのみを取得するには、1 つのメッセージを選択する基準を指定する必要があります)。
  • 両方のデータベースでクエリ権限が必要です (そうでない場合、両方の権限を持つ一部のユーザーは、たとえば crontab で定期的にテーブルまたはテーブルのサブセットをデータベースから別のデータベースにコピーする必要があります)。
  • 照合が一致しない場合があります。この場合、COLLATEを使用するか、1 つの DB のフィールドをCONVERT : CONVERT(db.table.field USING Latin1) を使用して別の DB の文字セットに変換することにより、2 つのテーブルのいずれかで照合を変更する必要があります。インデックスを使用するとパフォーマンスが低下します。2 つのテーブルのいずれかを変更できますが、'ed テーブルを使用しているクエリまたはアプリケーションを中断していないことを確認ALTERしてください(ピンチの場合は、データベース全体を適切に調整された UTF8 に変換してください)。
  • JOIN両方のテーブルに INDEX がある場合でも、テキスト フィールドの s はあまり効率的ではありません。メッセージの所有者を参照するために、一意の数値ユーザーIDを保持するメッセージ テーブルを用意することをお勧めします。異なるロジックを持つ 2 つの異なるデータベースがこの解決策に役立たない可能性があることは理解していますが、上記の「トリック」の 1 つ (「テーブルまたはそのサブセットをコピーする」) を適用して、変換および ID 化されたテーブルを定期的にエクスポートすることができます。 DBから他のDBへ。その 1 つの定期的なクエリはコストがかかりますが、後続のすべての JOIN は大きなメリットをもたらします。

テスト走行

これにより、2 つの異なるデータベースに同じ構造を持つ 2 つのテーブルが作成され、3 つ目のデータベースでそれらが結合されます。

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>
于 2012-10-02T06:02:56.080 に答える
0

以下のコードを試してください

SELECT * FROM dbA.Username JOIN dbB.PrivateMessage USING(Username);
于 2014-08-26T08:12:40.107 に答える
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

...接続内で両方のデータベースにアクセスできると仮定します。

それらにアクセスできない場合は、別のアプローチで作業する必要があります (クエリを実行する前に、あるテーブルを別のデータベースにコピーするなど)。

于 2012-10-02T06:01:32.107 に答える