我正在使用SQL Server 2008.
这是我的查询输出:
Reg_Id | ITSkillName
----------------------
118 | JAVASCRIPT
371 | PHP
371 | ANDROID
6170 | PHP
这里,Reg_Id
是外键。我希望Reg_Id
具有PHP和ANDROID技能。
所以我尝试了
SELECT *
FROM dbo.ITSkill AS is2
WHERE ITSkillName = 'PHP' AND ITSkillName = 'ANDROID'
但它返回0条记录。请帮我。谢谢。
答案 0 :(得分:3)
您需要JOIN
自己的表格才能获得所需的结果。
SELECT A.Reg_Id
FROM dbo.ITSkill A
INNER JOIN dbo.ITSkill B ON A.Reg_Id = B.Reg_Id AND B.ITSkillName='PHP'
WHERE A.ITSkillName='ANDROID'
如果您需要匹配任意数量的技能,但无法保证Reg_ID, ITSkillName
是唯一的,您可以使用CTE稍微修改Damien_The_Unbeliever的答案,如下所示:
;WITH UniqueSkills AS (SELECT DISTINCT Reg_ID, ITSkillName FROM dbo.ITSkill)
SELECT Reg_ID,COUNT(*) FROM UniqueSkills AS is2
WHERE ITSkillName IN(select Skill from @SearchSkills)
GROUP BY Reg_ID
HAVING COUNT(*) = (select COUNT(*) from @SearchSkills)
答案 1 :(得分:3)
这是一个关系划分问题。如果同时列出的Reg_ID
和ITSkillName
列在此表中是唯一的,那么我们就可以这样做:
SELECT Reg_ID,COUNT(*) FROM dbo.ITSkill AS is2
WHERE ITSkillName IN('PHP','ANDROID')
GROUP BY Reg_ID
HAVING COUNT(*) = 2
这通常通过调整IN
子句和预期计数来扩展到更多技能。
即。如果你有一个包含搜索技能的表值参数,你可以:
SELECT Reg_ID,COUNT(*) FROM dbo.ITSkill AS is2
WHERE ITSkillName IN(select Skill from @SearchSkills)
GROUP BY Reg_ID
HAVING COUNT(*) = (select COUNT(*) from @SearchSkills)
其中@SearchSkills
是表值参数。
答案 2 :(得分:3)
成套思考!您正在寻找的是两组的交叉点:具有PHP技能的那些和具有ANDROID技能的那些。 SQL有一个INTERSECT
运算符:
SELECT Reg_ID FROM dbo.ITSkill
WHERE Skill = 'PHP'
INTERSECT
SELECT Reg_ID FROM dbo.ITSkill
WHERE Skill = 'ANDROID'
答案 3 :(得分:2)
SELECT * FROM dbo.ITSkill AS is2
WHERE ITSkillName = 'PHP'
AND Reg_Id IN( SELECT DISTINCT Reg_Id
FROM dbo.ITSkill
WHERE ITSkillName = 'ANDROID')
<强>测试强>
DECLARE @t TABLE (Reg_Id INT,ITSkillName VARCHAR(20))
INSERT INTO @t
VALUES
(118,'JAVASCRIPT'),
(371,'PHP'),
(371,'ANDROID'),
(6170,'PHP')
SELECT * FROM @t AS is2
WHERE ITSkillName = 'PHP'
AND Reg_Id IN( SELECT DISTINCT Reg_Id
FROM @t
WHERE ITSkillName = 'ANDROID')
结果集
Reg_Id ITSkillName
371 PHP
答案 4 :(得分:0)
正如marc_s所说,INTERSECT是一个有效的选择。但是,由于查询优化器(至少在我的经验中)可能会选择执行查询的最佳方式,因此取决于有多少种技能,它可能会变得很重。
至少另一个选择是使用它:
SELECT s.*
FROM dbo.ITSkill s
JOIN
(SELECT Reg_ID
FROM dbo.ITSkill AS is2
WHERE ITSkillName IN ('PHP','ANDROID')
GROUP BY Reg_ID
HAVING COUNT(DISTINCT ITSkillName) = 2) SRC
ON SRC.Reg_ID = s.Reg_ID
现在显然,您需要更新HAVING COUNT值以匹配IN子句中的参数数量。在代码中,您有时可以连接数百个INTERSECT查询,这就是这个模型真正开始闪耀的地方。至少它应该在性能方面同样有效。
编辑:呸,刚刚注意到达米恩在那里有同样的想法!但是这也有加入以获得OP的结果所以我会留在这里。把信誉和财富交给达米恩。 ;)