在所有可能的字符串匹配上加入两个表

时间:2015-11-10 17:29:15

标签: sql-server join

我有两个表,学生和参考。我想在Reference.ReferenceCode上加入student.code。问题是学生可以在代码列中包含多个代码。我希望以这样一种方式加入,即当学生表中的学生有多个代码时,会生成多行。这就是我拥有的和我曾经尝试过的东西:

学生有两栏:ID&代码

|Student ID   |Code             |
|Student1     |Code1            |
|Student2     |Code1,Code2,Code3|

ReferenceCode有两列:ReferenceCode&描述

|ReferenceCode|Description      |
|Code1        |This is code 1   |
|Code2        |This is code 2   |
|Code3        |This is code 3   |

我尝试过使用Substring:

select a.studentID, a.code, b.ReferenceCode, b.Description
from Student a
left join Reference b --Have also tried inner join;  No difference
on b.ReferenceCode = substring(a.Code,1,len(b.ReferenceCode))

Substring生成下表。请注意,它只匹配第一个代码:

|Student ID   |Code             |ReferenceCode    |Description    |
|Student1     |Code1            |Code1            |This is code 1 |
|Student2     |Code1,Code2,Code3|Code1            |This is code 1 |

我也尝试了之类的方法:

select a.studentID, a.code, b.ReferenceCode, b.Description
from Student a
left join Reference b --Have also tried inner join;  No difference
on b.ReferenceCode like '%' + a.Code + '%'

但是这个方法导致一个表只匹配student表中只有一个代码的记录:

|Student ID   |Code             |ReferenceCode    |Description    |
|Student1     |Code1            |Code1            |This is code 1 |
*Student 2 doesn't pull*

我想看到的是:

|Student ID   |Code             |ReferenceCode    |Description    |
|Student1     |Code1            |Code1            |This is code 1 |
|Student2     |Code1,Code2,Code3|Code1            |This is code 1 |
|Student2     |Code1,Code2,Code3|Code2            |This is code 2 |
|Student2     |Code1,Code2,Code3|Code3            |This is code 3 |

2 个答案:

答案 0 :(得分:2)

您提出的解决方案会出现严重的性能问题。您是否能够更改数据库架构?如果是这样,以下是一个更好的方法。

您正在定义多对多映射。要正确映射它,您需要一个单独的“映射”表,其中仅包含学生和参考代码表中的ID。

所以你的新架构看起来像这样:

学生表

| Student ID (int) |
| 1                |
| 2                |

StudentCode表

| StudentId (int) | ReferenceCodeId (int) |
| 1               | 1                     |
| 2               | 1                     |
| 2               | 2                     |
| 2               | 3                     |

ReferenceCode表

|ReferenceCodeId (int) | Description     | 
|1                     |This is code 1   |
|2                     |This is code 2   |
|3                     |This is code 3   |

然后你的查询看起来像这样:

select s.StudentId, rc.Description 
from Student s 
left join StudentCode sc on s.StudentId = sc.StudentId
left join ReferenceCode rc on sc.ReferenceCodeId = rc.ReferenceCodeId

您的结果将如下所示:

|StudentId| Description     | 
|1        |This is code 1   |
|2        |This is code 1   |
|2        |This is code 2   |
|2        |This is code 3   |

快速搜索“sql多对多关系”应该为您提供重要的参考资料。

答案 1 :(得分:1)

您可以创建一个内联用户定义函数,该函数生成一列行(每个逗号分隔值的行) - 然后您就可以加入该列。

这种函数通常会有代码用XML标记替换分隔符,然后从XML中选择,它也可以是CLR或许多其他方法。您可以在this article中找到一些内容,您可以在那里找到不同的方法和效果比较结果。