单个MySQL字段,以逗号分隔值

时间:2012-07-13 01:52:23

标签: mysql sql

  

可能重复:
  mysql is array in multiple columns

我有两张桌子:

帖子表

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相关联的图像的页面上,我可以运行哪种查询来输出它的所有文件名?

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

SQLFiddle

但是,您应该真正规范化您的设计并在帖子和图像之间使用交叉引用表。这将是表示N:M(多对多)关系的最佳和最有效的方式。它不仅可以更有效地进行检索,而且还可以极大地简化更新删除图像关联。


  
    

...但就我用来添加的jQuery脚本而言,逗号分隔值更容易使用。

  

即使您使用交叉引用表正确表示N:M关系,您仍然可以获得CSV格式的imageid

假设您有一个posts_has_images表,其中包含主键字段(postidimageid):

您可以使用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的原子值 - 将其标准化。