如果在查询的前半段中找不到该产品代码,则需从另一张表中取回与该产品代码对应的一个已声明的值
我手头的第一张表对产品编码 SellPriceRule 存放固定价格,我也给出用于获取所需清单的查询。
问题在于对于某些客户——以客户7000192为例——结果中缺少某些产品条目,在这个例子中缺失的是 27MIETE10B 和 23RGWBBCA。
我还有另一张表,用来存放回滚/默认价格,如果第一张表没有设定价格的话。这张表叫 ProductSellPriceBand,它有一个bandnumber(1到 8),用于获取价格。我用的客户示例在区域AB(描述列)的bandnumber是 8。我需要知道如何添加代码:当第一条查询中的价格缺失时,能在 ProductSellPriceBand 表中以该band等级8、针对AB区域,抓取 productcode 的价格。
select
spr.Price, Per.PerCode, p.ProductCode, p.Description
from
SellPriceRule spr
left join
product p on p.ProductID = spr.ProductID
left join
customer c on c.CustomerID = spr.CustomerID
left join
Per on Per.PerID = spr.PricePerID
where
c.CustomerCode = '7000192'
and p.productcode in ('27MIETE10B', '22RGR45DHS', '23RGWBBCA', '22RGED4WA', '22RGED45WA')
这是我从查询得到的结果,缺少 ProductCode = 27MIETE10B 与 ProductCode = 23RGWBBCA 的价格:
| 价格 | PerCode | 产品代码 | 描述 |
|---|---|---|---|
| 11.77 | PNL | 22RGED45WA | RG RESIDENT D4.5 DL HARVARD RED45DCDN |
| 10.80 | PNL | 22RGED4WA | RG ESTATE D4 WALNUT ESTD4 |
| 7.42 | PNL | 22RGR45DHS | RG ESTATE D4.5 DL WALNUT ESTD45D |
我还想获取缺失值的另一张表是 ProductSellPriceBand,结构如下:
| 产品ID | 档位编号 | 描述 | 售价 |
|---|---|---|---|
| 4048 | 1 | AB Level 1 | 18.08 |
| 4048 | 2 | AB Level 2 | 15.85 |
| 4048 | 3 | AB Level 3 | 13.47 |
| 4048 | 4 | AB Level 4 | 12.8 |
| 4048 | 5 | AB Level 5 | 12.16 |
| 4048 | 6 | AB Level 6 | 11.91 |
| 4048 | 7 | AB Level 7 | 11.67 |
| 4048 | 8 | AB Level 8 | 11.45 |
| 4048 | 25 | WON Level 1 | 18.37 |
| 4048 | 26 | WON Level 2 | 17.23 |
| 4048 | 27 | WON Level 3 | 16.46 |
| 4048 | 28 | WON Level 4 | 15.76 |
| 4048 | 29 | WON Level 5 | 14.71 |
| 4048 | 30 | WON Level 6 | 13.78 |
| 4048 | 31 | WON Level 7 | 12.98 |
| 4048 | 32 | WON Level 8 | 12.3 |
| 4048 | 33 | EON Level 1 | 18.37 |
| 4048 | 34 | EON Level 2 | 17.23 |
| 4048 | 35 | EON Level 3 | 16.46 |
| 4048 | 36 | EON Level 4 | 15.76 |
| 4048 | 37 | EON Level 5 | 14.71 |
| 4048 | 38 | EON Level 6 | 13.78 |
| 4048 | 39 | EON Level 7 | 12.98 |
| 4048 | 40 | EON Level 8 | 12.3 |
| 4068 | 1 | AB Level 1 | 16.58 |
| 4068 | 2 | AB Level 2 | 14.53 |
| 4068 | 3 | AB Level 3 | 12.35 |
| 4068 | 4 | AB Level 4 | 11.73 |
| 4068 | 5 | AB Level 5 | 11.15 |
| 4068 | 6 | AB Level 6 | 10.92 |
| 4068 | 7 | AB Level 7 | 10.7 |
| 4068 | 8 | AB Level 8 | 10.49 |
| 4100 | 1 | AB Level 1 | 12.47 |
| 4100 | 2 | AB Level 2 | 9.98 |
| 4100 | 3 | AB Level 3 | 9.48 |
| 4100 | 4 | AB Level 4 | 9 |
| 4100 | 5 | AB Level 5 | 8.73 |
| 4100 | 6 | AB Level 6 | 8.47 |
| 4100 | 7 | AB Level 7 | 8.22 |
| 4100 | 8 | AB Level 8 | 7.76 |
| 4100 | 25 | WON Level 1 | 11.13 |
| 4100 | 26 | WON Level 2 | 10.44 |
| 4100 | 27 | WON Level 3 | 9.97 |
| 4100 | 28 | WON Level 4 | 9.54 |
| 4100 | 29 | WON Level 5 | 8.91 |
| 4100 | 30 | WON Level 6 | 8.36 |
| 4100 | 31 | WON Level 7 | 7.86 |
| 4100 | 32 | WON Level 8 | 7.42 |
| 4100 | 33 | EON Level 1 | 11.13 |
| 4100 | 34 | EON Level 2 | 10.44 |
| 4100 | 35 | EON Level 3 | 9.97 |
| 4100 | 36 | EON Level 4 | 9.54 |
| 4100 | 37 | EON Level 5 | 8.91 |
| 4100 | 38 | EON Level 6 | 8.36 |
| 4100 | 39 | EON Level 7 | 7.86 |
| 4100 | 40 | EON Level 8 | 7.42 |
| 4333 | 1 | AB Level 1 | 9.93 |
| 4333 | 2 | AB Level 2 | 9.43 |
| 4333 | 3 | AB Level 3 | 8.96 |
| 4333 | 4 | AB Level 4 | 8.52 |
| 4333 | 5 | AB Level 5 | 8.26 |
| 4333 | 6 | AB Level 6 | 8.01 |
| 4333 | 7 | AB Level 7 | 7.77 |
| 4333 | 8 | AB Level 8 | 7.54 |
| 4333 | 25 | WON Level 1 | 13.65 |
| 4333 | 26 | WON Level 2 | 12.79 |
| 4333 | 27 | WON Level 3 | 12.22 |
| 4333 | 28 | WON Level 4 | 11.7 |
| 4333 | 29 | WON Level 5 | 10.91 |
| 4333 | 30 | WON Level 6 | 10.23 |
| 4333 | 31 | WON Level 7 | 9.63 |
| 4333 | 32 | WON Level 8 | 9.1 |
| 4333 | 33 | EON Level 1 | 13.65 |
| 4333 | 34 | EON Level 2 | 12.79 |
| 4333 | 35 | EON Level 3 | 12.22 |
| 4333 | 36 | EON Level 4 | 11.7 |
| 4333 | 37 | EON Level 5 | 10.91 |
| 4333 | 38 | EON Level 6 | 10.23 |
| 4333 | 39 | EON Level 7 | 9.63 |
| 4333 | 40 | EON Level 8 | 9.1 |
| 7013 | 1 | AB Level 1 | 36.18 |
| 7013 | 2 | AB Level 2 | 32.56 |
| 7013 | 3 | AB Level 3 | 30.93 |
| 7013 | 4 | AB Level 4 | 29.38 |
| 7013 | 5 | AB Level 5 | 28.5 |
| 7013 | 6 | AB Level 6 | 27.64 |
| 7013 | 7 | AB Level 7 | 27.09 |
| 7013 | 8 | AB Level 8 | 26.55 |
我在看 EXCEPT,但那没有奏效
select
spr.Price, Per.PerCode, p.ProductCode, p.Description
from
SellPriceRule spr
left join
product p on p.ProductID = spr.ProductID
left join
customer c on c.CustomerID = spr.CustomerID
left join
Per on Per.PerID = spr.PricePerID
where
c.CustomerCode = '7000192'
and p.productcode in ('27MIETE10B', '22RGR45DHS', '23RGWBBCA', '22RGED4WA', '22RGED45WA')
except
select
psb.SellPrice,
Per.PerCode,
p.ProductCode,
psb.Description
from
[btprod].[dbo].[ProductSellPriceBand] psb
left join
Product p on p.ProductID = psb.ProductID
left join
Per on Per.PerID = psb.PerID
where
p.productcode in ('27MIETE10B', '22RGR45DHS', '23RGWBBCA', '22RGED4WA', '22RGED45WA')
and psb.Description like 'ab%'
and psb.BandNumber = '8'
欢迎给出任何建议。
解决方案
SELECT
COALESCE(spr.Price, psb.SellPrice) AS Price,
Per.PerCode,
p.ProductCode,
p.Description
FROM Product p
-- get the specific customer to use in our exact pricing join
LEFT JOIN customer c
ON c.CustomerCode = '7000192'
-- get the specific price rule for this exact customer
LEFT JOIN SellPriceRule spr
ON p.ProductID = spr.ProductID
AND spr.CustomerID = c.CustomerID
-- get the fallback price band (Band 8 for AB region)
LEFT JOIN ProductSellPriceBand psb
ON p.ProductID = psb.ProductID
AND psb.BandNumber = 8
AND psb.Description LIKE 'AB%'
-- get the PerCode based on whichever table provided the price
LEFT JOIN Per
ON Per.PerID = COALESCE(spr.PricePerID, psb.PerID)
-- filter for the specific products you are looking for
WHERE p.ProductCode IN (
'27MIETE10B',
'22RGR45DHS',
'23RGWBBCA',
'22RGED4WA',
'22RGED45WA'
)
由于缺少原始数据表,要实现你所提出的需求很困难。
理论上我已经按应有的方法实现了它。如果有什么地方不对,请在评论中留言,我会修改。
添加类似 MIN() 的聚合函数绝对需要使用 GROUP BY 子句对其余被选中的列进行分组。然而,这里有一个常见陷阱需要注意:如果某个产品对同一客户恰好有两条价格规则且价格不同,标准的 GROUP BY 将为该产品输出重复行(每个价格各一条),而不是选取唯一的“胜出”规则。
从你使用 [dbo] 来看,你应该是在使用SQL Server,因此有更好的解决方案——把 LEFT JOIN 换成一个 OUTER APPLY:
SELECT
COALESCE(spr.Price, psb.SellPrice) AS Price,
Per.PerCode,
p.ProductCode,
p.Description,
spr.RulePriority AS RulePrio
FROM Product p
LEFT JOIN customer c
ON c.CustomerCode = '7000192'
-- takes ONLY the single highest-priority rule for this product & customer
OUTER APPLY (
SELECT TOP 1 Price, PricePerID, RulePriority
FROM SellPriceRule
WHERE ProductID = p.ProductID
AND CustomerID = c.CustomerID
ORDER BY RulePriority ASC -- assuming lower number = higher priority
) spr
LEFT JOIN ProductSellPriceBand psb
ON p.ProductID = psb.ProductID
AND psb.BandNumber = 8
AND psb.Description LIKE 'AB%'
LEFT JOIN Per
ON Per.PerID = COALESCE(spr.PricePerID, psb.PerID)
WHERE p.ProductCode IN (
'27MIETE10B',
'22RGR45DHS',
'23RGWBBCA',
'22RGED4WA',
'22RGED45WA'
);
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。