0

我有以下 2 张桌子

表文章

id  subject     tags
---------------------
1   subject-1   2,4,5
2   subject-2   3,5
3   subject-3   1,2
4   subject-4   2,3,4
5   subject-5   3

表标签

id  tag_name
---------------------
1   php
2   jQuery
3   css
4   mysql
5   java

我正在尝试获得类似的结果

id => 1, subject => subject-1, tag_names => jQuery,mysql,java
id => 2, subject => subject-2, tag_names => css,java
id => 3, subject => subject-3, tag_names => php,jQuery

这是我当前的尝试,它仅返回第一个标签(例如,第 1 行的 2 而不是 2、4、5)

 1    SELECT
 2        table_article.id,
 3        table_article.subject,
 4        GROUP_CONCAT(table_tags.tag_name) AS tag_names
 5    FROM
 6        table_article
 7    LEFT JOIN
 8        table_tags
 9    ON
10        (table_tags.tag_id IN (table_article.tags))
11    GROUP BY
12        table_article.id
13    LIMIT
14        3

结果是

id => 1, subject => subject-1, tag_names => jquery
id => 2, subject => subject-2, tag_names => css
id => 3, subject => subject-3, tag_names => php

问题发生在第 10 行-> IN (table_article.tags)

我只是不知道我该如何解决这个问题,有人可以帮忙吗?

4

4 回答 4

3

您不能使用恰好包含逗号的字符串作为离散值列表。

换句话说:

ON table_tags.tag_id IN (2,4,5)

和这个不一样:

ON table_tags.tag_id IN ('2,4,5')

像 '2,4,5' 这样的字符串的数值是初始数字部分,第一个非数字字符之后的余数被忽略。所以字符串 '2,4,5' 的数值为 2。这不会是一个错误,但它不会让你得到你想要的,这是与逗号分隔的任何值的匹配列表。

MySQL 有一个内置函数FIND_IN_SET(),它可以理解包含逗号分隔值的字符串。该函数返回匹配值的位置,如果没有找到匹配,则返回 0。

ON FIND_IN_SET(table_tags.tag_id, '2,4,5') > 0

但这不能使用索引,它会迫使您运行表扫描,这会降低您的性能。需要明确的是,我不建议在连接条件下使用此功能。

答案是:不要将标签存储在逗号分隔的列表中。 请参阅我的答案,在数据库列中存储逗号分隔列表真的那么糟糕吗?

正如@Martin Lyne 建议的那样,将每行一个标签存储在一个单独的表中。这样,您可以查找正确的标签,=甚至可以索引列以获得更好的性能。

于 2012-11-02T20:38:01.893 回答
1

我以前没有在 ON 中看到过 IN(不是说它无效),但我会这样做ON table_tags.tag_id = table_article.tags)

所以你最终得到了多行

subject-1, query
subject-1, css
subject 2, query

然后GROUP BY将压缩表格并GROUP_CONCAT获取所有丢失的标签。

于 2012-11-02T20:32:13.123 回答
0

好吧,我会IN在这种情况下使用,它不起作用,替换它,FIND_IN_SET(table_tags.tag_id, table_article.tags) > 0你会没事的。尽管您确实应该对此进行规范化。

于 2012-11-02T20:35:27.280 回答
0

正如其他人所说,这不是一个好的设计。

相反,您可以通过以下方式更改表格设计:

table_article
   id
   subject

article_tag
   article_id
   tag_id

table_tags
   id
   tag_name

这样生活会容易得多:-)

于 2012-11-02T20:46:46.977 回答