2010-08-23 5 views
2

나는 두 개의 테이블이 있다면 : 나는 비슷한 결과를 얻을 쿼리를 수행하는 방법을 알아 내려고 노력하고있어범위가 다른 표에서 동적으로 나오는 숫자의 범위를 찾는 방법은 무엇입니까?

PersonID | Count 
----------------- 
1  | 45 
2  | 5 
3  | 120 
4  | 87 
5  | 60 
6  | 200 
7  | 31 

SizeName | LowerLimit 
----------------- 
Small | 0 
Medium | 50 
Large | 100 

을 :

PersonID | SizeName 
----------------- 
1  | Small 
2  | Small 
3  | Large 
4  | Medium 
5  | Medium 
6  | Large 
7  | Small 

기본적으로, 한 테이블의 알 수없는 수를 지정합니다 "범위 이름"과 관련 정수 범위. 그래서 사람 테이블에서 0에서 49까지의 카운트 범위는 '작은'지정을 얻습니다. 50-99는 'medium'등을 얻습니다.하지만 범위 이름이나 정수 값을 모르기 때문에 역동적이어야합니다. 단일 쿼리에서이 작업을 수행 할 수 있습니까? 아니면 가능성을 뛰어 넘기 위해 별도의 함수를 작성해야합니까?

+0

모두에게 감사드립니다. – Adam

답변

4

이 밖으로 시도 :

SELECT PersonID, SizeName 
FROM 
    (
    SELECT 
     PersonID, 
     (SELECT MAX([LowerLimit]) FROM dbo.[Size] WHERE [LowerLimit] < [COUNT]) As LowerLimit 
    FROM dbo.Person 
    ) A 
    INNER JOIN dbo.[SIZE] B ON A.LowerLimit = B.LowerLimit 
+0

고맙습니다. 이것은 좋은 정직하고 깨끗한 솔루션 인 것 같습니다. – Adam

1
With Ranges As 
    (
    Select 'Small' As Name, 0 As LowerLimit 
    Union All Select 'Medium', 50 
    Union All Select 'Large', 100 
    ) 
    , Person As 
    (
    Select 1 As PersonId, 45 As [Count] 
    Union All Select 2, 5 
    Union All Select 3, 120 
    Union All Select 4, 87 
    Union All Select 5, 60 
    Union All Select 6, 200 
    Union All Select 7, 31 
    ) 
    , RangeStartEnd As 
    (
    Select R1.Name 
     , Case When Min(R1.LowerLimit) = 0 Then -1 Else MIN(R1.LowerLimit) End As StartValue 
     , Coalesce(MIN(R2.LowerLimit), 2147483647) As EndValue 
    From Ranges As R1 
     Left Join Ranges As R2 
      On R2.LowerLimit > R1.LowerLimit 
    Group By R1.Name 
    ) 
Select P.PersonId, P.[Count], RSE.Name 
From Person As P 
    Join RangeStartEnd As RSE 
     On P.[Count] > RSE.StartValue 
      And P.[Count] <= RSE.EndValue 

내가 공통 테이블 표현식은 SQL 서버 2005 +에 존재하는 (줄여서 CTE)를 사용하고 있지만,이 여러 쿼리를 수행 할 수 있습니다 어디 임시 테이블을 작성하여 RangeStartEnd cte에 해당하는 것을 저장하십시오. 트릭은 시작 열과 끝 열이있는 뷰를 만드는 것입니다.

1
SELECT p.PersonID, Ranges.SizeName 
FROM People P 
JOIN 
    (
    SELECT SizeName, LowerLimit, MIN(COALESCE(upperlimit, 2000000)) AS upperlimit 
    FROM (
     SELECT rl.SizeName, rl.LowerLimit, ru.LowerLimit AS UpperLimit 
     FROM Ranges rl 
     LEFT OUTER JOIN Ranges ru ON rl.LowerLimit < ru.LowerLimit 
     ) r 
    WHERE r.LowerLimit < COALESCE(r.UpperLimit, 2000000) 
    GROUP BY SizeName, LowerLimit 
    ) Ranges ON p.Count >= Ranges.LowerLimit AND p.Count < Ranges.upperlimit 
ORDER BY PersonID 
관련 문제