1

私のMySQLテーブル構造は、次のような2つのテーブルで構成されています。

UserId field1 field2
1       XXX    YYY
2       ABC    DDD
3       EEE    FFF
.
.
.
n       GGG    DDD


UserId  attribute
1        blah
1        adfadf 
1        ddad
2        adff
3        adfa
3        sdff
.
.
.
z        adss

表1には、IDごとに1つのレコードしかありません。表2には、IDごとにM個のレコードがあります。表1と表2のIDは関連しています。私のクエリは次のようになります。

SELECT
    t1.`UserId`,
    t1.`field1`,
    t1.`field2`,
    t2.`attribute`
FROM `table1` AS `t1`
    LEFT JOIN `table2` AS `t2` ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3

クエリは次を返します。

3 EEE FFF adfa
3 EEE FFF sdff

それぞれに重複したレコードを返したくありません。単一の行を返したい、のようなもの

3 EEE FFF (adfa,sdff)

4番目のフィールドは、指定されたユーザーIDに対して返されるすべての属性を含むデータ構造(配列?結果セット?)です。

編集:::CONCATを含む多くのソリューションがあり、これをCSVに変換します。カンマを含むフィールドは、物事を台無しにする可能性がありますか?

4

6 に答える 6

1

私のコメントの要約:

単一のフィールドに存在できる唯一のデータ構造は、プリミティブデータ型です。

この場合、コンマ区切りの文字列を使用することになります。そこに配列を入れることはできません。そこにデータセットをネストすることもできません。リレーショナルデータベースは、すでに行っているように、複数の行のデータを使用して目的を達成します。また、複数の値を1つのフィールドに集約することは、リレーショナルデータベースでは非常に苦痛なアンチパターンと見なされます。非常に多くの異なる方法でデータを照会するのは面倒です。

要するに:

  • 別々の行の別々の値= good
  • 単一のフィールドに結合された値= bad

現在の構造はリレーショナルデータベースの通常のベストプラクティスであり、JSON_ENCODED文字列オプションはお勧めしません。私の推奨は、あなたがそれをする必要がある特別な理由がない限り、これを全くしないことです。もしあなたがそれを持っているなら、私はそれを知りたいと思います。そうすれば、このアプローチが本当に役立つかどうかについてコメントできるかもしれません。そして、通常、あなたが求めることをやろうとすることは、長期的には役に立ちません。

あなたの例のように、すでにコンマを含む2つの値がある場合はどうなりますか?それはただトラブルを求めているだけです。


不要なネットワークトラフィックが本当に心配な場合は、両方のテーブルから個別に選択し、ネストされたループで処理してください。*(ネストされたループをできるだけ単純にするために、両方のデータセットが[この場合はuser_idによって]同じ方法で順序付けられていることを確認してください。)*

于 2012-07-05T21:57:39.913 に答える
1
SELECT
    t1.`UserId`,
    t1.`field1`,
    t1.`field2`,
    CONCAT'(',GROUP_CONCAT(DISTINCT t2.`attribute`SEPARATOR ','),')') AS Attributes
FROM `table1` AS `t1`
    LEFT JOIN `table2` AS `t2` ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3
GROUP BY  t1.`UserId`,t1.`field1`,t1.`field2`
于 2012-07-05T21:45:08.710 に答える
0

これがSQLのバリアントで機能するかどうかはわかりません。T-SQLでは、これはローカル変数を導入することで実現できます。この小さなサンプルが示しています。ご存じない方のために説明すると、「WITH」句は「共通テーブル式」であり、使用するサンプルデータを簡単に取得できます。

declare @temp as varchar(10);
select @temp = '';

with vals as (
    select '1' as a
    union select '2' as a
)
select @temp = @temp +  a + ','
from vals

select '(' + @temp + ')'

クエリの場合は、これをに変更するだけselect @temp = @temp + attributeです。もちろん、最後の余分なコンマを削除するために、小さな部分文字列コードを追加することをお勧めします。

于 2012-07-05T21:44:04.170 に答える
0

mysqlを使用している場合、それを行う1つの方法はGROUP_CONCATを使用することです。

于 2012-07-05T21:44:05.823 に答える
0

mysqlを使用する場合は、GROUP_CONCATを試してください。これが当てはまる場合は、GROUP_CONCATの長さが最大であることに注意してください。これは、セッション変数「group_concat_max_len」を使用して調整できます。

于 2012-07-05T21:44:29.393 に答える
0

group_concat演算子を使用して、結合とグループ化を行う必要があります。

SELECT t1.`UserId`, t1.`field1`, t1.`field2`,
       concat('(', group_concat(t2.`attribute`, ','), ')')
FROM `table1` `t1` LEFT JOIN
     `table2` AS `t2`
     ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3 
group by t1.`UserId`, t1.`field1`, t1.`field2`
于 2012-07-05T21:45:59.440 に答える