如何使用第一个表中的逗号分隔值从另一个表中选择行? [复制]
Posted
技术标签:
【中文标题】如何使用第一个表中的逗号分隔值从另一个表中选择行? [复制]【英文标题】:How to select row/s from an other table using a comma-separated value from the first table? [duplicate] 【发布时间】:2021-12-11 11:37:18 【问题描述】:有没有办法使用第一个表中的逗号分隔值从另一个表中选择行?
表 1.faculty
subject |
---|
101, 102 |
104 |
103, 105 |
表 2.subject
code | subject |
---|---|
101 | subject 1 |
102 | subject 2 |
103 | subject 3 |
104 | subject 4 |
105 | subject 5 |
预期输出:
subject | subject |
---|---|
101, 102 | subject 1, subject 2 |
104 | subject 4 |
103, 105 | subject 3, subject 5 |
我已经试过了:
SELECT faculty.subject, subject_offered.code, subject_offered.subject
FROM faculty
LEFT JOIN subject_offered
ON subject_offered.code
IN (faculty.subject)
但faculty
中具有多个值(逗号分隔)的行在subject
表的代码和主题列中显示为NULL。
my output
【问题讨论】:
表达您的模式/示例表数据的最理想方式是创建一个 sql fiddle。然后志愿者可以立即使用真实数据并自信地发布答案。 Is storing a delimited list in a database column really that bad?FIND_IN_SET()
怎么样?我无法想象您是 Stack Overflow 上第一个询问如何克服“糟糕的表格设计”挑战的人。
您使用的是 SQL Server 吗?我没有在问题的任何地方看到这一点。
真正的解决方案当然是改变你的数据模型。当您对单独的值感兴趣时,不要存储逗号分隔的值。这违反了数据库规范化,而不是如何使用关系数据库。修复此问题后,编写查询将变得更容易。一般来说,它们也会更快。并且 DBMS 将能够保证数据的一致性(即您在集合中找到的 ID 确实存在)。
我的错,我使用的是 SQL 服务器。感谢您的建议
【参考方案1】:
SELECT f.subject,
GROUP_CONCAT(s.subject ) as subject
FROM faculty as f
INNER JOIN subjects s
ON FIND_IN_SET(s.code, f.subject)
GROUP BY f.subject;
Run in Fiddle
【讨论】:
你怎么知道 OP 正在使用 SQL Server?你和他们坐在同一个房间吗? @mickmackusa 好吧,我很抱歉。显然,你是对的。 这个答案看起来很像这个答案的底部:***.com/a/16508385/2943403 问题是 mysql 标记的,而不是 SQL Server。 @TBA,您是否编辑了整个答案(之前用 SQL Server 编写),并用@Akina 的答案完全替换了它?这简直是在偷窃。【参考方案2】:更新
请参阅the answer by @Akina 以获得完整正确和更清洁的解决方案。
虽然这是一个非常糟糕的表格设计,但仍有办法解决这个问题。
解决方案
SELECT faculty_subject AS faculty_subject_codes, GROUP_CONCAT(subject ORDER BY code ASC) AS subjects
FROM (
SELECT faculty.subject as faculty_subject, subject.*
FROM subject
JOIN faculty
ON faculty.subject LIKE CONCAT('%', subject.code, '%')
) fa GROUP BY faculty_subject;
给予
faculty_subject_codes | subjects |
---|---|
101,102 | subject 1,subject 2 |
103,105 | subject 3,subject 5 |
104 | subject 4 |
结帐my fiddle for your question
说明
由于faculty.subject
是逗号分隔值,因此您不能通过subject.code
进行常规连接,解决方法是使用JOIN
和LIKE
子句代替。
SELECT faculty.subject as faculty_subject, subject.*
FROM subject
JOIN faculty
ON faculty.subject LIKE CONCAT('%', subject.code, '%');
faculty_subject | code | subject |
---|---|---|
101,102 | 101 | subject 1 |
101,102 | 102 | subject 2 |
103,105 | 103 | subject 3 |
104 | 104 | subject 4 |
103,105 | 105 | subject 5 |
现在我们有多个具有相同的 Faculty_subject 的行,例如代码 103 和 105。接下来是将这些重复的行合并到一个条目中,我们将使用 GROUP CONCAT
语句和 GROUP BY
来执行此操作faculty_subject
SELECT faculty_subject AS faculty_subject_codes, GROUP_CONCAT(subject ORDER BY code ASC) AS subjects
FROM (
SELECT faculty.subject as faculty_subject, subject.*
FROM subject
JOIN faculty
ON faculty.subject LIKE CONCAT('%', subject.code, '%')
) fa GROUP BY faculty_subject;
【讨论】:
错误。添加(10, 'subject 6')
...db-fiddle.com/f/dwBwNENqBtywdgqB9LYaZu/2
是的,@Akina,我还在考虑如何解决这个问题,可能你的解决方案是最好的......
正式的 ON CONCAT(',', faculty.subject, ',') LIKE CONCAT('%,', subject.code, ',%')
可能会修复 - 但它过于复杂。
太棒了!我只是不明白为什么主题列只显示一个主题并根据我设备中的 Faculty_subject 列中的值的数量重复自身,但它在 sqlfiddle 中工作正常【参考方案3】:
SELECT t1.subject, GROUP_CONCAT(t2.subject)
FROM faculty t1
JOIN subjects t2 ON FIND_IN_SET(t2.code, t1.subject)
GROUP BY t1.subject;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=3e40ab353ff1e0a1cde678225fa63ed2
【讨论】:
我不知道FIND_IN_SET
函数,这个答案比我的简单多了。干得好!
@ThangLeQuoc 唯一可能的问题 - 在字符串列中使用 CSV 的人可能会在逗号后添加多余的空格(可能是为了某种美感?),这需要在应用 FIND_IN_SET 之前删除这些空格符号。跨度>
我建议不要使用这样的别名。别名应该使查询更易于阅读。助记名称就是这种情况,例如 f 代表教师,s 代表学科。对于像 t1 和 t2 这样的任意名称,情况并非如此。恰恰相反,这样的别名会使查询比没有它们时更难阅读。以上是关于如何使用第一个表中的逗号分隔值从另一个表中选择行? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
从一个表中选择一个逗号分隔的值,并使用 SQL Server 中的函数在另一个表中的 where 条件中使用它
SQL INNER JOIN - 根据另一行的值从另一个表中选择数据