0

I am trying to create a decision statement to determine if the 5 variables (@skill1, @skill2, @skill3, @skill4, @skill5) are not null or empty.

The people_skills table contains different skills for each person. So there may be more than 1 record for a person. The lkp_skills contains the names of those skills.

Based on the 5 different skill fields, I want to ignore the empty string. I also want to search for the strings within the lkp_skills table. If the variable matches the s.skill field of that table then i want it to return that record. If there are multiple skills then I want it to return records that have Both of those skills.

What is the best way of doing this?

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
4

2 回答 2

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子句的顺序,您将开始收到错误。

于 2013-08-20T19:41:57.070 回答
0

您可以在 WHERE 子句中使用 CASE 语句,或者如果 SQL 在存储过程中,则只需使其动态化(当然,您必须处理安全性)。

在 where 子句中使用 T-SQL 中的 CASE?

或者

DECLARE @SQL varchar(max);

SET @SQL = 'SELECT ......';

IF LEN(@Skill1) > 0 
BEGIN
    SET @SQL = @SQL + '<your statement>'
END 
于 2013-08-20T19:20:54.010 回答