2013-08-20 1 views
0

5 개의 변수 (@ skill1, @ skill2, @ skill3, @ skill4, @ skill5)가 null 또는 비어 있지 않은지 결정하기 위해 의사 결정 진술을 작성하려고합니다.SQL 결정 문

people_skills 테이블에는 각 사람마다 다른 기술이 있습니다. 따라서 한 사람에 대해 두 가지 이상의 기록이있을 수 있습니다. 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

:

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 절 표현식은 지정한 순서대로 실행되지 않을 수도 있습니다. 예를 들어 zip_code가 숫자가 아닌 경우 sp_getDistance이 오류를 throw하면 쿼리가 작동하지만 나중에 쿼리 최적화 프로그램이 WHERE 절의 순서를 변경하고 오류가 발생하기 시작합니다.

+0

나는 스킬 테이블을 임시 테이블이나 테이블 변수에 넣었으므로 스킬을 더 추가하면 다시 코딩 할 필요가 없습니다. 또한 순위를 포함시킬 수도 있습니다 (예 : 개수가 아닌 합계가있는 가중치 부여 기술). – Rawheiser

0

당신은 WHERE 절에 CASE 문을 사용하거나 그냥 저장 프로 시저에서의 경우 SQL 동적으로 만들 수 있습니다 (당신은 물론, 보안을 처리해야 할 것이다).

using CASE in T-SQL in the where clause?

또는 더이 개 기술은 동일한 이름이 없다고 가정 할 경우,이 쿼리는 귀하의 능력을 모두 가진 모든 사람들이 돌아갑니다

DECLARE @SQL varchar(max); 

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

IF LEN(@Skill1) > 0 
BEGIN 
    SET @SQL = @SQL + '<your statement>' 
END 
+0

당신이이 요구 사항을 가지고 있기 때문에'Case'만으로도 충분하지 않을 것이라고 생각합니다. * 여러 기술이있는 경우 두 가지 기술을 모두 갖춘 레코드를 반환하고 싶습니다. * OP는 아마 ' lskp_skills.ID) = @ SkillCount'도 마찬가지입니다. –