如何使用第一个表中的逗号分隔值从另一个表中选择行? [复制]

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 进行常规连接,解决方法是使用JOINLIKE 子句代替。

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 CE 中的表中构建逗号分隔列表?

从一个表中选择一个逗号分隔的值,并使用 SQL Server 中的函数在另一个表中的 where 条件中使用它

SQL INNER JOIN - 根据另一行的值从另一个表中选择数据

我可以使用 SQL 将存储为 CSV(逗号分隔值)的表列的内容拆分为新表中的单独行吗?

将一张excel表中的数据全部粘贴到txt文本文件中,如何做