2016-04-22 190 views
0

我有兩個表[Price Range]SQL查詢返回以下結果集

ID | Price 
1 | 10 
2 | 50 
3 | 100 

Product

ID | Name | Price 
1 | Prod1 | 5 
2 | Prod2 | 10 
3 | Prod3 | 20 
4 | Prod4 | 30 
5 | Prod5 | 50 
6 | Prod5 | 60 
7 | Prod6 | 120 

我需要產品具有特定的價格區間,即由價格區間加入這兩個表進行關聯,並要求結果集如下:

ProductPriceRange 

ID | Name | Price | PriceRangeID 
1 | Prod1 | 5  | Null 
2 | Prod2 | 10 | 1 
3 | Prod3 | 20 | 1 
4 | Prod4 | 30 | 1 
5 | Prod5 | 50 | 2 
6 | Prod5 | 60 | 2 
7 | Prod6 | 120 | 3 
+0

那麼,你的問題是什麼? – qxg

+0

我的問題是使用sql join來獲取結果數據集。它不能用簡單的左連接完成, –

回答

0

如果Price Range ID是上升爲價格那麼你可以簡單:

SELECT p.ID, 
     p.Name, 
     MAX(pr.ID) as PriceRangeID 
FROM Product p 
LEFT JOIN PriceRange pr 
    ON p.Price >= pr.Price 
GROUP BY p.ID, p.Name 

輸出:

ID   Name PriceRangeID 
----------- ----- ------------ 
1   Prod1 NULL 
2   Prod2 1 
3   Prod3 1 
4   Prod4 1 
5   Prod5 2 
6   Prod5 2 
7   Prod6 3 
Warning: Null value is eliminated by an aggregate or other SET operation. 

(7 row(s) affected) 

新的CTE的另一種方式:

;WITH new_price_range AS (
SELECT pr1.ID, 
     MAX(pr1.Price) as PriceB, 
     MIN(ISNULL(pr2.Price-1,pr1.Price*10)) as PriceT 
FROM PriceRange pr1 
LEFT JOIN PriceRange pr2 
    ON Pr1.Price < Pr2.Price 
GROUP BY pr1.ID) 

SELECT p.ID, 
     p.Name, 
     pr.ID as PriceRangeID 
FROM Product p 
LEFT JOIN new_price_range pr 
    ON p.Price between pr.PriceB and pr.PriceT 

在這種CTE我們產生這樣的:

ID   PriceB  PriceT 
----------- ----------- ----------- 
1   10   49 
2   50   99 
3   100   1000 

(3 row(s) affected) 

輸出:

ID   Name PriceRangeID 
----------- ----- ------------ 
1   Prod1 NULL 
2   Prod2 1 
3   Prod3 1 
4   Prod4 1 
5   Prod5 2 
6   Prod5 2 
7   Prod6 3 

(7 row(s) affected) 
2

您可以使用此

select id, name, price, 
    (select id 
    from PriceRange 
    where price = (select max(price) 
        from PriceRange 
        where price <= a.price) 
    ) as PriceRangeID 
from Product a 
2

這樣做的另一種方式是通過構建一個ranges CTE與包含pricefrom/PriceTo列,就像這樣:

with rangesWithRn as (
    select [ID], [Price], 
    ROW_NUMBER() OVER(ORDER BY [Price]) as rn 
    FROM #PriceRange), 
ranges as (
    select r1.ID, r1.Price as PriceFrom, COALESCE(r2.Price, 2147483647) as PriceTo 
    FROM rangesWithRn r1 LEFT JOIN rangesWithRn r2 
    ON r2.rn = r1.rn + 1 
) 
SELECT p.[ID], p.[Name], p.[Price], r.[ID] 
from #Product p LEFT JOIN ranges r 
    ON p.Price >= r.PriceFrom and p.Price < r.PriceTo 

結果:

ID   Name Price  ID 
----------- ----- ----------- ----------- 
1   Prod1 5   NULL 
2   Prod2 10   1 
3   Prod3 20   1 
4   Prod4 30   1 
5   Prod5 50   2 
6   Prod5 60   2 
7   Prod6 120   3 

(7 row(s) affected) 
+0

我同意你的方法來完成加入,但是多個加入和多個條件會導致查詢運行速度比平時慢 – Dean

1

使用Outer Apply

SELECT p.ID, 
     p.Name, 
     p.Price, 
     PriceRangeTable.ID as PriceRangeID 
FROM Product p 
OUTER APPY(
SELECT TOP(1) ID 
FROM PriceRange pr 
WHERE p.Price >= pr.Price)PriceRangeTable