MySQL 使用 LEFT JOIN 从 2 个表(非关系表)中获取行

标签 mysql left-join

我有以下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/

相关文章:

mysql - 如何从批处理文件执行 mysql 脚本,使用属性文件读取用户名和密码

mysql - 如何使用查询解决 sql 导入错误 #1064 (joomla)

MySQL INNER JOIN 带有子查询和最大日期的空行

mysql - 重复的列名 'user_id'问题

php - 带左连接的 SQL 查询结果和带 PHP 的结果数组

mysql - 如何使用 SQL 查询获取该表单的数据

mysql - 使用 eRuby 连接 MySQL 时出现问题

php - 困惑... MYSQL + JOIN + PAGINATION

sql - 是否可以在 Access 的连接条件中使用子查询?

php - mysql_fetch_array()/mysql_fetch_assoc()/mysql_fetch_row()/mysql_num_rows 等...期望参数 1 是资源