1

group concat なしで複数の行を1つの行に結合する方法は?

以下のようなテーブルがあると考えてください:

テーブルユーザー:

uid | name
-----------
 1  | A
 2  | B

テーブルのメタ:

uid | metaid | metaval
------------------------
 1  |   1    |  Jsep St.
 1  |   2    |  St. Oak No. 15
 2  |   1    |  Dt. San Joseph
 2  |   2    |  St. Oak No. 17
 2  |   3    |  OA.

テーブルのメタプロパティ:

metaid | metakey
-----------------
  1    | school
  2    | address 
  3    | dept
  4    | acc

学校と住所でユーザーを選択したいので、クエリは

SELECT 
    uid, name, metaval 
FROM user 
INNER JOIN meta ON meta.uid = user.uid 
WHERE meta.metaid = 1 OR meta.metaid = 2

それは出力します

| UID | Name | MetaVal         |
--------------------------------
|  1  |  A   |  Jsep St.       |
|  1  |  A   |  St. Oak No. 15 |

私が望む結果はこのようなものです

uid | name | school  |    address 
-------------------------------------
 1  |   A  | Jsep St.| St. Oak No. 15

グループ連結では、値が「学校」と「住所」のメタプロパティが別の列ではなく1 つの列にある

2回参加しようとするとうまくいきますが、エレガントではないと思います

SELECT 
    uid, name, T1.metaval as school, T2.metaval as address 
FROM user 
INNER JOIN meta T1 ON T1.uid = user.uid AND T1.metaid = 1 
INNER JOIN meta T2 ON T2.uid = user.uid AND T2.metaid = 2

より良い解決策はありますか?

4

2 に答える 2

1

より良い解決策はありますか?

簡潔な答え

いいえ。

中程度の長さの答え

クエリにはいくつかの問題があります。

  • userテーブルを含めるのを忘れていました。
  • 読みやすいように SQL をフォーマットします。
  • LEFT JOIN一部のデータが欠落している可能性がある場合は、使用を検討してください。

これを試して:

SELECT uid, name, T1.metaval AS school, T2.metaval AS address
FROM user
LEFT JOIN meta T1 ON T1.uid = user.uid AND T1.metaid = 1
LEFT JOIN meta T2 ON T2.uid = user.uid AND T2.metaid = 2

長い答え

はい、そのクエリは醜いですが、問題はクエリではなく、データベースの設計です。使用している設計は、entity-attribute-value (EAV) と呼ばれます。可能であれば、EAV 設計の使用は避けてください。EAV を使用するたびに、すべてのクエリが複数の結合モンスターに変わります。各値を同じ行の別々の列に格納できれば、はるかに簡単です。

もちろん、EAV を使用しなければならない状況もあります。次に、クエリが長く、読みにくく、洗練されておらず、遅いことを受け入れる必要があります。これは、柔軟なスキーマを持つこととのトレードオフです。

于 2012-07-27T08:02:33.620 に答える
0

多分これは短い答えです:

SELECT uid, name,
       max(  case when meta.metaid = 1 then metaval  else '' end ) as school,
       max(  case when meta.metaid = 2 then metaval  else '' end ) as address
FROM user  
INNER JOIN meta 
    ON meta.uid = user.uid  
WHERE meta.metaid = 1 OR meta.metaid = 2 
group by uid, name
于 2012-07-27T09:31:18.227 に答える