我正在尝试创建一个决策声明,以确定5个变量(@ skill1,@ skill2,@ skill3,@ skill4,@ skill5)是否为空或空。
people_skills表包含每个人的不同技能。因此,一个人可能有超过1条记录。 lkp_skills包含这些技能的名称。
基于5个不同的技能领域,我想忽略空字符串。我还想在lkp_skills表中搜索字符串。如果变量与该表的s.skill字段匹配,那么我希望它返回该记录。如果有多种技能,那么我希望它能够返回具有这两种技能的记录。
这样做的最佳方式是什么?
DECLARE @zip char(5) = '61265', -- Zip Code
@skill1 varchar(50) = 'sql', -- Job Skill 1
@skill2 varchar(50) = 'css', -- Job Skill 2
@skill3 varchar(50) = '', -- Job Skill 3
@skill4 varchar(50) = '', -- Job Skill 4
@skill5 varchar(50) = '', -- Job Skill 5
@distance int = 5 -- Distance in miles
SELECT p.people_id, p.first_name, p.last_name, p.address_1, p.address_2, p.city, p.[state],
p.zip_code, (dbo.sp_getDistance(@zip, zip_code)) AS miles, s.skill
FROM people p
INNER JOIN people_skills ps ON ps.people_id = p.people_id
INNER JOIN lkp_skills s ON ps.skill_id = s.skill_id
WHERE (ISNUMERIC(p.zip_code) = 1 AND LEN(RTRIM(LTRIM(p.zip_code))) = 5)
AND p.ROLE_ID <= 4
AND ((dbo.sp_getDistance(@zip, zip_code)) <= @distance)
AND
-- DECISION STATEMENT GOES HERE --
ORDER BY miles
答案 0 :(得分:3)
如果您认为没有2个技能具有相同的名称,那么此查询将返回拥有您所有技能的所有人:
DECLARE @zip char(5), @distance int
DECLARE @Skill1 varchar(50), @Skill2 varchar(50), @Skill3 varchar(50), @Skill4 varchar(50), @Skill5 varchar(50)
SET @zip = '61265'
SET @distance = 5
SET @skill1 = 'sql'
SET @skill2 = 'css'
-- Count how many skills we should search for...
DECLARE @SkillCount int
SET @SkillCount = 0
IF @skill1 IS NOT NULL AND @skill1 != '' SET @SkillCount = @SkillCount + 1
IF @skill2 IS NOT NULL AND @skill2 != '' SET @SkillCount = @SkillCount + 1
IF @skill3 IS NOT NULL AND @skill3 != '' SET @SkillCount = @SkillCount + 1
IF @skill4 IS NOT NULL AND @skill4 != '' SET @SkillCount = @SkillCount + 1
IF @skill5 IS NOT NULL AND @skill5 != '' SET @SkillCount = @SkillCount + 1
SELECT p.people_id, p.first_name, p.last_name, p.address_1, p.address_2, p.city, p.[state],
p.zip_code, (dbo.sp_getDistance(@zip, zip_code)) AS miles
FROM people p
WHERE (ISNUMERIC(p.zip_code) = 1 AND LEN(RTRIM(LTRIM(p.zip_code))) = 5)
AND p.ROLE_ID <= 4
AND ((dbo.sp_getDistance(@zip, zip_code)) <= @distance)
AND p.people_id IN (
-- Get the list of people who have all of the needed skills
SELECT ps.people_id
FROM people_skills ps
INNER JOIN lkp_skills s
ON ps.skill_id = s.skill_id
WHERE s.name IN ( @skill1, @skill2, @skill3, @skill4, @skill5 )
GROUP BY ps.people_id
-- This is the key. This filters the list of people to make
-- sure that the person has ALL of the skills.
HAVING COUNT(*) = @SkillCount
)
ORDER BY miles
另请注意,距离搜索中的WHERE
子句表达式不保证按您指定的顺序运行。例如,如果sp_getDistance
如果zip_code不是数字则抛出错误,那么您的查询现在可以正常工作,但在将来的某个时候,查询优化器可能会更改WHERE
子句的顺序而您会开始出错。
答案 1 :(得分:0)
您可以在WHERE子句中使用CASE语句,或者只是在存储过程中使SQL动态化(当然,您必须处理安全性)。
using CASE in T-SQL in the where clause?
OR
DECLARE @SQL varchar(max);
SET @SQL = 'SELECT ......';
IF LEN(@Skill1) > 0
BEGIN
SET @SQL = @SQL + '<your statement>'
END