【问题标题】:mysql join on csv field?mysql加入csv字段?
【发布时间】:2014-01-09 01:09:11
【问题描述】:

我有如下三张表

http://sqlfiddle.com/#!2/82212/6:

CREATE TABLE IF NOT EXISTS `cat` (
  `id` int(15) NOT NULL AUTO_INCREMENT,
  `color_options` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
);
INSERT INTO `cat` (`id`, `color_options`) VALUES (1, '1,2,3,4');


CREATE TABLE IF NOT EXISTS `template` (
  `id` int(15) NOT NULL AUTO_INCREMENT,
  `cat_id` int(15) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

INSERT INTO `template` (`id`, `cat_id`) VALUES (1, 1);


CREATE TABLE IF NOT EXISTS `color` (
  `id` int(15) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  `code` varchar(6) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
);

INSERT INTO `color` (`id`, `name`, `code`) VALUES
(1, 'Black', '000000'),
(2, 'Red', 'FF0000'),
(3, 'Blue', '0000FF'),
(4, 'Green', '00FF00');

如果我跑了

SELECT * 
FROM template
LEFT JOIN cat ON cat.id=template.id;

然后我会得到

id  cat_id  color_options

1   1   1,2,3,4

如何获取文本中的颜色选项(黑色、红色、蓝色、绿色)而不是纯数字?

我尝试使用 join,但它不适用于 csv 字段。

提前致谢

【问题讨论】:

  • 规范化你的数据库,你就不会遇到这样的问题了。如果你不知道这意味着什么,我听说过这本书的好东西,数据库设计为凡人。

标签: mysql sql join


【解决方案1】:

MySQL 有一个函数FIND_IN_SET(),它处理逗号分隔值的字符串。它返回匹配元素的位置,如果没有找到匹配则返回 0。详情请见documentation

例如:

SELECT * 
FROM template
JOIN cat ON cat.id=template.id
JOIN color ON FIND_IN_SET(color.id, cat.color_options)

请注意,使用逗号分隔的列表会破坏使用索引来提高查询效率的任何机会。它还有很多其他的缺点。见Is storing a delimited list in a database column really that bad?

【讨论】:

  • 这将为每种颜色返回 1 行,我认为 OP 希望将所有颜色名称放在一列中
  • 这正是我想要做的事情的完美答案。我很惊讶有多少 StackOverflow 答案长达数十行,并在 FIND_IN_SET 一直存在时创建了临时表或定义的函数。
【解决方案2】:

带有 GROUP_CONCAT() 的子查询

SELECT *,(SELECT GROUP_CONCAT(name) FROM color WHERE CONCAT(',',cat.color_options,',') LIKE CONCAT('%,',color.id,',%')) color_options_text
FROM template
LEFT JOIN cat ON cat.id=template.id

其他人使用了我的新功能,这也有效且阅读起来更干净

SELECT *,(SELECT GROUP_CONCAT(name) FROM color WHERE FIND_IN_SET(color.id,cat.color_options)) color_options_text
FROM template
LEFT JOIN cat ON cat.id=template.id

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 2012-06-01
    • 1970-01-01
    • 2017-02-13
    • 2011-04-25
    • 2013-01-24
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    相关资源
    最近更新 更多