简体   繁体   English

SQL查询返回以下结果集

[英]Sql Query to return following result set

I have two tables [Price Range] 我有两张桌子[Price Range]

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

and Product : 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

I need to associate product with specific price range ie join both table by price range and require result set like this: 我需要将产品与特定的价格范围相关联,即按价格范围将两个表都连接起来,并要求这样的结果集:

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

You can use this 你可以用这个

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

Another way of doing this is by building a ranges CTE with the PriceFrom/PriceTo columns, like this: 另一种方法是通过使用PriceFrom / PriceTo列构建ranges CTE,如下所示:

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

Result: 结果:

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)

Use Outer Apply 使用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

If Price Range ID's are ascending as price then you can simple: 如果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

Output: 输出:

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)

Another way with new cte: 新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

In this cte we generate this: 在此CTE中,我们生成以下代码:

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

(3 row(s) affected)

Output: 输出:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM