我有以下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
table_tags:
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)
。
我只是想不出如何解决这个问题,有人可以帮忙吗?
最佳答案
您不能将恰好包含逗号的字符串用作离散值列表。
换句话说:
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
但这不能使用索引,它会强制您运行表扫描,这会降低您的性能。明确地说,我不建议在连接条件中使用此函数。
答案是:不要将标签存储在以逗号分隔的列表中。请参阅我对 Is storing a comma separated list in a database column really that bad? 的回答。
按照@Martin Lyne 的建议,将每行一个标签存储在一个单独的表中。这样您就可以使用 =
查找正确的标签,您甚至可以为该列建立索引以获得更好的性能。
关于MySQL 使用 LEFT JOIN 从 2 个表(非关系表)中获取行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13202508/