web-dev-qa-db-ja.com

1つの行を別のテーブルの複数の行に結合する

エンティティ(それらを人と呼ぶことにする)とプロパティ(1人が任意の数のプロパティを持つことができる)のテーブルがあります。例:

Name  Age
--------
Jane  27
Joe   36
Jim   16

プロパティ

Name   Property
-----------------
Jane   Smart
Jane   Funny
Jane   Good-looking
Joe    Smart
Joe    Workaholic
Jim    Funny
Jim    Young

私は、年齢に基づいて人々を選択し、そのプロパティのすべてまたは一部を返す効率的な選択を記述したいと思います。

Ex: People older than 26
Name Properties
Jane Smart, Funny, Good-looking
Joe Smart, Workaholic

プロパティの1つとプロパティの総数を返すことも可能です。

クエリは効率的である必要があります。ピープルテーブルには数百万行、プロパティテーブルには数十万行あります(したがって、ほとんどの人にはプロパティがありません)。一度に数百の行が選択されています。

それを行う方法はありますか?

23
Ghostrider

使用する:

   SELECT x.name,
          GROUP_CONCAT(y.property SEPARATOR ', ')
     FROM PEOPLE x
LEFT JOIN PROPERTIES y ON y.name = x.name
    WHERE x.age > 26
 GROUP BY x.name

PROPERTIES.property値のコンマ区切りのリストを返すために、MySQL関数GROUP_CONCAT( documentation )が必要です。

PROPERTIESテーブルに値を持たないPEOPLEレコードを含めるために、JOINではなくLEFT JOINを使用しました。PROPERTIESテーブルに値を持つ人のリストのみが必要な場合は、以下を使用します。

   SELECT x.name,
          GROUP_CONCAT(y.property SEPARATOR ', ')
     FROM PEOPLE x
     JOIN PROPERTIES y ON y.name = x.name
    WHERE x.age > 26
 GROUP BY x.name

これは一例ですが、 "John Smith"の数を考えると、名前を使用して参照整合性を保つことはできません。数値であるuser_idを割り当てることは、より良い選択です。

25
OMG Ponies
SELECT x.name,(select GROUP_CONCAT(y.Properties SEPARATOR ', ')
FROM PROPERTIES y 
WHERE y.name.=x.name ) as Properties FROM mst_People x 

これを試して

4
mayur awati

INNER JOINを使用して、2つのテーブルをリンクできます。 JOINの詳細

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.Name = P.Name
WHERE P.Name = 'Joe' -- or a specific age, etc

ただし、多くの場合、これらのようなテーブルに一意の 主キー を追加し、速度を上げるために インデックス を作成する方がはるかに高速です。

テーブルPeopleにフィールドidがあるとします。
そしてテーブルPropertiesには、それらをリンクするためのフィールドpeopleIdがあります

次に、クエリは次のようになります。

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.id = P.peopleId
WHERE P.Name = 'Joe'
3
Alec