Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 用于从两个表中匹配逗号分隔值的查询_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql server 用于从两个表中匹配逗号分隔值的查询

Sql server 用于从两个表中匹配逗号分隔值的查询,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有两张桌子。学生和工作。 我需要寻找具备这份工作所要求的所有技能的学生 Student Job StudentId MandSkills JobPostId MandSkills 208 2,16,17 36 2,16,18 209 2,16 210 2,18,34 211 2

我有两张桌子。学生和工作。 我需要寻找具备这份工作所要求的所有技能的学生

    Student                      Job
StudentId MandSkills           JobPostId    MandSkills
  208        2,16,17              36         2,16,18
  209        2,16       
  210        2,18,34        
  211        2,16,17        
  212        2,17,16,23     
  213        2,16,17        
  214        2,16,17        
  215        2,18,17,28     
  217        2,16,17
我写了一个问题

SELECT 
   S.StudentId, S.MandSkills, JP.items 
FROM 
   Split((SELECT MandSkills FROM JobPosts WHERE JobPostId = 36),',') JP, 
   Students S   
WHERE 
    JP.items IN (SELECT items FROM Split(S.MandSkills,','))
[Split()获取逗号分隔的字符串值作为输入,并以表格形式返回单独的值]

返回如下结果:

studentId MandSkills items
    208 2,16,17 2
    209 2,16    2
    210 2   2
    211 2,16,17 2
    212 2,16,17 2
    213 2,16,17 2
    214 2,16,17 2
    215 2,16,17 2
    217 2,16,17 2
    218 2,16,17,26  2
    219 2,16    2
    221 2,16    2
    208 2,16,17 16
    209 2,16    16
    211 2,16,17 16
    212 2,16,17 16
    213 2,16,17 16
    214 2,16,17 16
    215 2,16,17 16
    217 2,16,17 16
    218 2,16,17,26  16
    219 2,16    16
    220 16,17   16
    221 2,16    16
它只检查一种技能

我想挑选具备这三种技能的学生

请帮帮我

提前谢谢

-Aarti

试试这个(我还没有测试过):


你可以试试这个。。但我猜。。我不知道这样做是否可行:

select * 
from Student s
join Job j on (select count(*)-sum(case when jms.items is not null then 1 else 0 end)
               from split(j.MandSkills,',') sms
               left join split(s.MandSkills,',') jms on sms.items=jms.items)=0

我建议更改您的模式,不要将技能列表作为CSV值存储在每个表中。性能将受到影响,因为您最终不得不将值拆分,并且不会使用索引

相反,我将创建两个额外的表:

StudentSkill
-------------
StudentId
SkillId

JobSkill
--------
JobPostId
SkillId
在每种情况下,这两个字段都构成主键,并为每列引用相应的主表(即StudentId->Student.StudentId)

现在您有了一个模式,它可以生成可搜索的查询(可以使用索引)

因此,一个适合您的查询是:

;WITH CTEJobSkills AS
(
SELECT SkillID 
FROM JobSkill
WHERE JobPostID = 1
)

SELECT s.StudentID 
FROM Student s
WHERE NOT EXISTS
    (
        SELECT *
        FROM CTEJobSkills js
            LEFT JOIN StudentSkill ss ON js.SkillID = ss.SkillID AND ss.StudentID = s.StudentID
        WHERE ss.SkillID IS NULL
    )
这是一个相当快速的尝试,因此可能有其他方法来构造该查询-如果可以更改模式,那么值得玩转

SELECT sid FROM
    (
    Select sid, jid, ssk, jsk FROM
        (SELECT id sid, regexp_split_to_table(stud.skill, ',') ssk FROM stud) s,
        (SELECT id jid, regexp_split_to_table(job.skill, ',') jsk FROM job WHERE id = 36) j
    WHERE ssk = jsk
    ORDER BY sid, jsk, ssk
    ) jn
GROUP BY sid
HAVING count(*) = (SELECT count(*) FROM (SELECT id jid, regexp_split_to_table(job.skill, ',') jsk FROM job WHERE id = 36) sj) 
抱歉,我使用POSTGRESQL进行快速检查。regexp_split_to_表等于SQL Server中的split。
我还建议进一步规范您的桌子结构。每个id使用一行->技能对将使您摆脱拆分操作。

将技能等信息的完整列表存储在一列中是一种糟糕的数据库设计。我们有什么表格和关系??我会将你的设计重新构建为一个学生表,一个技能表,以及两者之间的链接表——这样,你可以为任何学生分配任意数量的技能。同样,也要以相同的方式将技能表链接到您的作业。1)您的表可能不在1NF中,因为
MandSkills
包含非标量数据,当然SQL(Server)不太适合查询此类数据,因此对每个值使用一行进行建模;2) 您需要的关系运算符被称为“关系分部”,例如,谷歌it。我感谢您的建议。我也知道这是一个糟糕的数据库设计,但一个网站是活的,有很多数据存储。由于一些需求的变化,我需要这样设计数据库。目前无法重新设计数据库。谢谢。@Richard:是的。成功了。完美的解决方案。谢谢。
;WITH CTEJobSkills AS
(
SELECT SkillID 
FROM JobSkill
WHERE JobPostID = 1
)

SELECT s.StudentID 
FROM Student s
WHERE NOT EXISTS
    (
        SELECT *
        FROM CTEJobSkills js
            LEFT JOIN StudentSkill ss ON js.SkillID = ss.SkillID AND ss.StudentID = s.StudentID
        WHERE ss.SkillID IS NULL
    )
SELECT sid FROM
    (
    Select sid, jid, ssk, jsk FROM
        (SELECT id sid, regexp_split_to_table(stud.skill, ',') ssk FROM stud) s,
        (SELECT id jid, regexp_split_to_table(job.skill, ',') jsk FROM job WHERE id = 36) j
    WHERE ssk = jsk
    ORDER BY sid, jsk, ssk
    ) jn
GROUP BY sid
HAVING count(*) = (SELECT count(*) FROM (SELECT id jid, regexp_split_to_table(job.skill, ',') jsk FROM job WHERE id = 36) sj)