【发布时间】:2018-05-05 03:08:51
【问题描述】:
我有一个无法开始工作的递归选择问题,感觉几乎就在那里,但不一定。
我有两张桌子,其中:
表 1 - 产品列表
List ProductCode SortNumber
------------------------------------
1 A 1
1 B 2
1 F 3
1 G 4
1 K 5
2 C 1
2 A 2
3 B 1
3 K 2
3 G 3
表 2 - 产品价格
ProductType Client ProductCode Price
---------------------------------------------------
Type 1 1 A 100
Type 1 1 A 150
Type 1 1 B 200
Type 1 1 B 120
Type 1 1 F 150
Type 2 1 A 200
Type 2 1 A 300
Type 2 1 B 300
Type 2 1 F 400
Type 2 1 G 125
Type 2 1 G 75
Type 1 2 A 190
Type 1 2 A 130
Type 1 2 A 200
Type 1 2 B 270
Type 1 2 B 180
Type 1 2 F 130
Type 2 2 A 210
Type 2 2 A 100
Type 2 2 B 350
Type 2 2 F 200
Type 2 2 G 175
Type 2 2 G 95
Type 2 2 K 65
我想要实现的是,当我请求产品列表 1 时,它将获得与产品代码相关的所有最高价格。如果产品类型 1 没有价格,它将检查产品类型 2 的最高价格。如果没有对应的类型 2 价格,则值为 0。
因此,所需的输出是当我为所有客户请求价格表 1 时(比如这里为客户 1 和 2),所需的输出应该是
Client ProductCode SortNumber PriceToDisplay
---------------------------------------------------
1 A 1 150
1 B 2 200
1 F 3 150
1 G 4 125 (No Type 1, so we get type 2 price)
1 K 5 0 (No Type 1, 2 Price for Product K)
2 A 1 200
2 B 2 270
2 F 3 130
2 G 4 175
2 K 5 65
尝试过的解决方案:CTE 方法
因为我的印象是这可能是一个递归选择,所以我想到了使用 CTE。我有这个问题 -
(注意注释代码 - -- 和 pp1.ProductCode = pp2.ProductCode)
Declare @List int = 1
;With ClientCTE As (
Select Distinct Client From ClientsTable
),
RecursiveSelect As (
Select p1.Client
, l.ProductCode
, l.SortOrder
, p1.Price As P1Price
, p2.Price As P2Price
, Case when p1.Price Is Null Then Case When p2.Price Is Null Then 0 Else p2.Price End
Else p1.Price End As PriceToDisplay
From ProductList l
Left Join (
Select Distinct pp.Client, pp.ProductCode, Max(pp.Price) As ItemPrice From ProductPrice pp
Left Join ClientCTE c On c.Client = pp.Client
Where pp.ProductType = 1
Group By pp.Client, pp.ProductCode) p1 On p1.ProductCode = l.ProductCode
Left Join (
Select Distinct pp.Client, pp.ProductCode, Max(pp.Price) As ItemPrice From ProductPrice pp
Left Join ClientCTE c On c.Client = pp.Client
Where pp.ProductType = 2
Group By pp.Client, pp.ProductCode) p2 On p2.Client = p1.Client
Where pp1.Client = pp2.Client
-- And pp1.ProductCode = pp2.ProductCode **this commented code**
And l.List = 1
)
Select Distinct Client, ProductCode, SortOrder, Max(P1Price), Max(P2Price)
From RecursiveSelect
Group By Client, ProductCode, SortOrder
调查结果 - CTE
如果代码被注释,它将:
- 正确获取价格
- 但是,由于产品价格表中没有产品代码 G 和类型 1 的 K 价格,因此无法正确显示
结果
Client ProductCode SortNumber PriceToDisplay
---------------------------------------------------
1 A 1 150
1 B 2 200
1 F 3 150
(missing G and K product codes)
2 A 1 200
2 B 2 270
2 F 3 130
2 G 4 175
2 K 5 65
如果代码没有注释,它将:
- 所有产品代码都会出现但价格错误
- 显示的价格是 Price1 表中的最高价格,因此与客户无关
结果
Client ProductCode SortNumber PriceToDisplay
---------------------------------------------------
1 A 1 WRONG PRICE
1 B 2 WRONG PRICE
1 F 3 WRONG PRICE
1 G 4 WRONG PRICE
1 K 5 WRONG PRICE
2 A 1 WRONG PRICE
2 B 2 WRONG PRICE
2 F 3 WRONG PRICE
2 G 4 WRONG PRICE
2 K 5 WRONG PRICE
我想我只需要对查询进行一项调整,但我无法确定确切的位置。未注释的代码返回正确的值,但考虑到它是左连接,为什么它不返回丢失的左表值?
【问题讨论】:
标签: sql-server tsql common-table-expression