Sql server SQL决策语句

Sql server SQL决策语句,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我正在尝试创建一个决策语句,以确定5个变量@skill1、@skill2、@skill3、@skill4、@skill5是否为null或空 人员技能表包含每个人的不同技能。因此,一个人可能有不止一条记录。lkp_技能包含这些技能的名称 基于5个不同的技能字段,我想忽略空字符串。我还想在lkp_技能表中搜索字符串。如果变量与该表的s.skill字段匹配,那么我希望它返回该记录。如果有多个技能,那么我希望它返回同时具有这两个技能的记录 这样做的最佳方式是什么 DECLARE @zip char(5)

我正在尝试创建一个决策语句,以确定5个变量@skill1、@skill2、@skill3、@skill4、@skill5是否为null或空

人员技能表包含每个人的不同技能。因此,一个人可能有不止一条记录。lkp_技能包含这些技能的名称

基于5个不同的技能字段,我想忽略空字符串。我还想在lkp_技能表中搜索字符串。如果变量与该表的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

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


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


如果您可以假设没有两种技能具有相同的名称,则此查询将返回拥有您所有技能的所有人员:

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在邮政编码不是数字的情况下抛出错误,那么您的查询现在可以工作,但在将来的某个时候,查询优化器可能会更改WHERE子句的顺序,您将开始收到错误。

如果您可以假设没有两种技能具有相同的名称,然后,此查询将返回拥有您所有技能的所有人员:

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在邮政编码不是数字的情况下抛出错误,那么您的查询现在可能可以工作,但在将来的某个时候,查询优化器可能会更改WHERE子句的顺序,您将开始收到错误。

请提供更多详细信息,以了解其他部分的等信息。你想要第一个有值的技能变量吗?我将编辑我的原始帖子以反映其余部分。请为其余部分提供更多细节,等等。你想要第一个有值的技能变量吗?我将编辑我的原始帖子以反映其余的。我认为案例在这里是不够的,因为你有这个要求。如果有多个技能,那么我希望它返回同时具有这两个技能的记录。OP可能需要一些类似于countlkp_skills.ID=@SkillCount的东西。我认为这里的Case不够,因为您有这个要求。如果有多个技能,那么我希望它返回同时具有这两个技能的记录。OP可能需要一些东西,比如在那里有countlkp_skills.ID=@SkillCount,我会把技能列表放在临时表或表变量中,因此添加更多技能不需要重新编码。这也将允许排名也包括在内,即加权技能的总和,而不是计数等…我会把技能列表中的临时表或表变量,所以添加更多的技能将不需要重新编码。这也将允许排名也包括在内,即加权技能的总和,而不是计数,等等。。。