2013-08-20 44 views
0

我想創建一個判斷語句來確定5個變量(@ skill1,@ skill2,@ skill3,@ skill4,@ skill5)是否爲空或空。SQL決策陳述

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

請詳細說明「剩餘部分等」部分。你想要第一個具有價值的技能變量嗎? – David

+0

我將編輯我的原始帖子以反映其餘內容。 – HKImpact

回答

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子句的順序,您將開始收到錯誤。

+0

我會把技能列表放在一個臨時表或表變量中,因此添加更多技能不需要重新編碼。這也可以讓排名也包括在內(即用總和而不是數量來加權的技能)等等。 – Rawheiser

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 
+0

我不認爲'Case'在這裏就足夠了,因爲你有這個要求*如果有多種技能,那麼我希望它能夠返回具有這兩種技能的記錄。* OP可能需要像'Having count( lkp_skills.ID)= @ SkillCount'在那裏 –