我有3张这样的表:
图像(~10,000行)
id | place_id | filename
---|----------|----------
1 | 4 | abc.jpg
2 | 3 | def.jpg
3 | 4 | ghi.jpg
4 | 7 | jkl.jpg
标签(~100行)
id | name |
---|----------|
1 | tagA |
2 | tagB |
3 | tagC |
4 | tagD |
tagsToImages(~30,000行)
id | tag_id | image_id
---|----------|----------
1 | 1 | 4
2 | 3 | 2
3 | 2 | 4
4 | 1 | 1
例如,最后一个表显示id = 1的标记与id = 4的图像链接。
我有两个问题,一个非常简单(我认为!),还有一个问题。
简单问题
给定一个place_id,如何列出该place_id中包含图像的所有标签?一个例子是:
给定place_id = 7,返回tagA,tagB。
难以回答
我想要做的是选择具有某个place_id的所有图像,并将每个图像与标签列表相关联,如下所示:
选择all with place_id = 4,同时加入标签信息。
filename | tags
-----------------------
abc.jpg | tagA
ghi.jpg | tagA, tagB
通过执行多个查询在PHP中做得更好,还是可以使用MYSQL执行此操作?
答案 0 :(得分:2)
SELECT i.place_id, t.name as tag_name
FROM images i
INNER JOIN tagsToImages tti ON (tti.image_id = i.id)
INNER JOIN tags t ON (t.id = tti.tag_id)
WHERE i.place_id = 7
SELECT i.filename, GROUP_CONCAT(t.name SEPARATOR ',') AS tags
FROM images i
INNER JOIN tagsToImages tti ON (tti.image_id = i.id)
INNER JOIN tags t ON (t.id = tti.tag_id)
WHERE i.place_id = 4
GROUP BY i.filename
如果可能的话,最好避免多次查询
*请注意GROUP_CONCAT
的最大长度由group_concat_max_len
变量控制。如果您希望获得一长串连接字符串,则可能需要更改默认值。
<强>更新强>
如果您希望查询显示没有相关标签的图片,请将INNER JOIN
更改为LEFT JOIN
s
答案 1 :(得分:1)
简单问题
SELECT name
FROM images
RIGHT JOIN tagsToImages on images.id = tagsToImages.image_id
RIGHT JOIN tags ON tags.tag_id = tagsToImages.image_id
WHERE place_id = '7'
答案 2 :(得分:0)
对于简单的问题,请使用效率更高的join
:
select
t.name as `Tag`
from
images i
left join
tagsToImages ti on ti.image_id = i.id
left join
tags t on t.id = ti.tag_id
where
place_id = $place_id
对于疑难问题,请参阅GROUP_CONCAT
:http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
答案 3 :(得分:0)
使用join发出单个查询比添加循环,多个数据结构和手动比较PHP中的值更好。