且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在连接字段中使用逗号分隔列表连接两个表

更新时间:2021-10-14 23:16:10

在数据库字段中使用逗号分隔列表是一种反模式,应不惜一切代价避免.
因为在 SQL 中再次提取这些逗号分隔的值是一个 PITA.

Using comma separated lists in a database field is an anti-pattern and should be avoided at all costs.
Because it is a PITA to extract those comma separated values out agian in SQL.

相反,您应该添加一个单独的链接表来表示类别和电影之间的关系,如下所示:

Instead you should add a separate link table to represent the relationship between categories and movies, like so:

Table categories
  id integer auto_increment primary key
  name varchar(255)

Table movies
  id integer auto_increment primary key
  name varchar(255)

Table movie_cat
  movie_id integer foreign key references movies.id
  cat_id integer foreign key references categories.id
  primary key (movie_id, cat_id)

现在可以了

SELECT m.name as movie_title, GROUP_CONCAT(c.name) AS categories FROM movies m
INNER JOIN movie_cat mc ON (mc.movie_id = m.id)
INNER JOIN categories c ON (c.id = mc.cat_id)
GROUP BY m.id

回到你的问题
或者,您可以使用您的数据

Back to your question
Alternativly using your data you can do

SELECT m.name as movie_title
  , CONCAT(c1.name, if(c2.name IS NULL,'',', '), ifnull(c2.name,'')) as categories 
FROM movies m
LEFT JOIN categories c2 ON 
 (replace(substring(substring_index(m.categories, ',', 2),
  length(substring_index(m.categories, ',', 2 - 1)) + 1), ',', '') = c2.id)
INNER JOIN categories c1 ON 
 (replace(substring(substring_index(m.categories, ',', 1), 
  length(substring_index(m.categories, ',', 1 - 1)) + 1), ',', '') = c1.id)

请注意,最后一个查询仅适用于每部电影有 2 个或更少类别的情况.

Note that the last query only works if there are 2 or fewer categories per movie.