我有两张桌子:
帖子表
PostID | Gallery
1 | 4,7,8,12,13
2 | 1,2,3,4
3 | 5,8,9
4 | 3,6,11,14
Gallery中的值是Images表中的主键:
图像表
ImageID | FileName
1 | something.jpg
2 | lorem.jpg
3 | ipsum.jpg
4 | what.jpg
5 | why.jpg
我之所以这样做而不是仅仅将PostID键添加到Images表是因为这些图像可以与很多不同的帖子相关联。我想我可以为关系添加另一个表,但是就我用来添加它的jQuery脚本而言,逗号分隔值更容易使用。
如果我在一个需要与PostID 3相关联的图像的页面上,我可以运行哪种查询来输出它的所有文件名?
答案 0 :(得分:25)
您可以使用此解决方案:
SELECT b.filename
FROM posts a
INNER JOIN images b ON FIND_IN_SET(b.imageid, a.gallery) > 0
WHERE a.postid = 3
但是,您应该真正规范化您的设计并在帖子和图像之间使用交叉引用表。这将是表示N:M(多对多)关系的最佳和最有效的方式。它不仅可以更有效地进行检索,而且还可以极大地简化更新和删除图像关联。
...但就我用来添加的jQuery脚本而言,逗号分隔值更容易使用。
即使您使用交叉引用表正确表示N:M关系,您仍然可以获得CSV格式的imageid
:
假设您有一个posts_has_images
表,其中包含主键字段(postid
,imageid
):
您可以使用GROUP_CONCAT()
为每个imageid
获取postid
的CSV:
SELECT postid, GROUP_CONCAT(imageid) AS gallery
FROM posts_has_images
GROUP BY postid
答案 1 :(得分:1)
就正确的SQL而言,你肯定应该有另一个表来关联这两个而不是分隔列。
那就是说,你可以这样做:
SELECT * FROM Images i WHERE EXISTS (SELECT 1 FROM Posts p WHERE p.PostID = 3 AND i.ImageID IN (p.Gallery))
答案 2 :(得分:1)
这是你的问题。这是糟糕的设计,因为您需要搜索Gallery
字段的特定值。您可以使用FIND_IN_SET
,但查询速度很慢。转到Gallery的原子值 - 将其标准化。