0

1 つのクエリでマージしたい 2 つの mysql テーブルがあります。それは例によって最もよく説明されています:

table: users
| user_id | username |
| 1       | jason    |
| 2       | justin   |

table: user_data
| user_id | key   | data            |
| 1       | email | jason@email.com |
| 1       | phone | 555-123-4567    |
| 2       | email | justin@email.com|
| 2       | phone | 555-765-4321    |


query results:
| user_id | username | email            | phone        |
| 1       | jason    | jason@email.com  | 555-123-4567 |
| 2       | justin   | justin@email.com | 555-765-4321 |

キーはすべてのユーザー間でかなり均一であると想定できます (つまり、すべてのユーザーが電子メールと電話を持っています)。私の最初の考えは、このようなことをすることですが、より良い方法があるかどうか興味があります:

SELECT *,e.data as email,p.data as phone FROM users u
  LEFT JOIN user_data AS e ON e.user_id=u.user_id AND `key`='email'
  LEFT JOIN user_data AS p ON p.user_id=u.user_id AND `key`='phone';
4

2 に答える 2

3

すべてのユーザーがメールと電話を持っている

それでは、元のテーブルにそれらの列を追加してみませんか?

table: users
| user_id | username | email | phone  |
| 1       | jason    | ....  | ....   |
| 2       | justin   | ....  | ....   |

これにより、クエリがはるかに簡単かつ高速になります。

使用している設計はEntity-attribute-value (EAV) と呼ばれ、多くの属性があり、それらがまばらに設定されている場合に一般的に役立ちます。

テーブルのデザインを変更できない、または変更したくない場合、クエリに加える唯一の変更は を使用しないことSELECT *です。列を明示的にリストします。

于 2012-04-27T22:18:47.427 に答える
0

@Mark Ba​​yersに同意します。

ただし、自分の設計に固執する場合は、次のことを考慮する必要があります。1 人のユーザーが複数の電子メールを持つ可能性はありますか? または複数の電話?その場合、ユーザーごとに電話と電子メールのすべての組み合わせを取得します。

それぞれのフィールドにすべてのデータを含む、各ユーザーに 1 つの行だけが必要な場合は、これを試すことができます。

SELECT     users.id, users.username
,          GROUP_CONCAT(IF(user_data.key = 'email', user_data.data, NULL)) emails
,          GROUP_CONCAT(IF(user_data.key = 'phone', user_data.data, NULL)) phones
FROM       users
INNER JOIN user_data
ON         users.id = user_data.user_id
GROUP BY   users.id
于 2012-04-27T22:26:18.753 に答える