0

画像、色、タグの 3 つのテーブルがあります。各画像には 2 色と少なくとも 1 つのタグがあります。そして、ユーザーがタグや色を個別に検索できるようにします。

問題は、テーブルに参加しているときに、列に同じ値を持つ行が複数回取得されることです。

SELECT images.id, tag, color
FROM images
JOIN tags ON tags.image_id = images.id
JOIN colors ON colors.image_id = images.id
WHERE images.id = 1

I get:
image_id: 1, tag: sky, color: blue
image_id: 1, tag: cloud, color: blue
image_id: 1, tag: sky, color: white
image_id: 1, tag: cloud, color: white

But the result I want is something like:
image_id: 1, tag1: sky, tag2: cloud, color1: blue, color2: white

これはどういうわけか可能ですか?それとも、データベースの設計を変更する必要がありますか?

4

1 に答える 1

1

この関数group_concat()は、すべてのタグまたは色の値を 1 つのフィールドに入れます。任意のセパレーターを使用します。

SELECT images.id, group_concat(distinct tag separator ', ') as tags,
       group_concat(distinct color separator ', ') as colors
FROM images
left JOIN tags ON tags.image_id = images.id
left JOIN colors ON colors.image_id = images.id
WHERE images.id = 1
group by images.id

(group by厳密に言えば、1 つのグループに絞り込むため、この場合は必要ありません。ただし、where句を削除して、複数の ID についてこれを確認することもできます。)

キーワードは重複を防ぎます。distinctこれは、クエリがタグと色の間のデカルト積を生成するため重要です。4 つのタグと 3 つの色がある場合、クエリは ID ごとに 4*3=12 行を生成します。結合を左外部結合に変更したので、ID にタグがないか色がないことがわかります。

実際には、出力として 1tag1 tag2 color1 color2` を要求し,ます。値が 2 つ以下の場合は幸運です。,, and

SELECT images.id,
       min(tag) as tag1, max(tag) as tag2,
       min(color) as color1, max(color) as color2
FROM images
left JOIN tags ON tags.image_id = images.id
left JOIN colors ON colors.image_id = images.id
WHERE images.id = 1
group by images.id

より多くの色またはタグを使用すると、問題が発生します。SQL クエリには固定数の列があります。つまり、id に新しい色が追加されたからといって、別の列を追加することはできません。また、MySQL では列挙が困難です (可能ですが、標準 SQL では不可能です)。2 つ以上の色またはタグがある場合は、 を使用してgroup_concat()ください。

于 2013-04-26T19:32:01.113 に答える