2010-08-23 89 views
2

如果我有兩個表:如何查找範圍來自另一個表的dyamically的數字的範圍?

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獲得'中等'等,但我需要它是動態的,因爲我不知道範圍名稱或整數值。我可以在單個查詢中做到這一點,還是必須編寫一個單獨的函數來循環遍歷可能性?

+0

謝謝大家的幫忙! – Adam 2010-08-24 01:53:24

回答

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 2010-08-24 01:52:38

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 

雖然我使用共表表達式(CTE的簡稱)只在SQL Server 2005+存在,這可以用多個查詢來完成,你創建一個臨時表來存儲相當於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