我有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
这有可能吗?或者我应该改变数据库设计?
答案 0 :(得分:1)
函数group_concat()
将把所有标记或颜色值放到一个字段中,不管你喜欢什么样的分隔符:
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
不是必需的,因为您要过滤到一个组。但是您可能想要消除where
子句并查看多个ID。)< / p>
distinct
关键字可以防止重复,这很重要,因为您的查询会在标记和颜色之间生成笛卡尔积。如果您有4个标签和3种颜色,则查询会为每个ID生成4 * 3 = 12行。我确实将连接更改为左外连接,因此您将看到缺少标签或缺少颜色的ID。
您实际上请求1tag1 ,
tag2 ,
color1 , and
color2`作为输出。好吧,如果最多有两个值,那么你很幸运:
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)。如果您有两种以上的颜色或标签,请使用group_concat()
。