我正在尝试在SQL Server中实现价格回退系统。我想为产品定义一套越来越具体的价格(例如:按地区,商店,仓库等),可能会或可能不会定义,并且能够选择最具体的价格(即:报告中定义了大多数参数的一个。
例如,我可能有以下数据:
Region
--------
1
2
Store
--------
1
2
3
Product | Region | Store | Price
--------------------------------
Foo | NULL | NULL | 1.0
Foo | 1 | NULL | 2.0
Foo | 1 | 1 | 2.5
Foo | 1 | 2 | 2.3
所以如果我想知道产品Foo的价格......
为了简单起见,我可以假设商店总是比区域更具体,商店只能存在于一个地区。
此数据的架构如下:
CREATE TABLE Prices(
ID int IDENTITY(1,1) NOT NULL,
Product int NOT NULL,
Region int NULL,
Store int NULL,
Price money NOT NULL,
CONSTRAINT PK_Prices PRIMARY KEY CLUSTERED (ID ASC),
CONSTRAINT IX_Prices UNIQUE NONCLUSTERED (Product ASC, Region ASC, Store ASC)
)
除了在代码中处理这些数据之外,如何根据(地区,商店)查询此表以获取每种产品的有效价格列表?
答案 0 :(得分:4)
试试这个:
所有产品的 EDIT ,每个产品都列出一次,即使给定的地区和商店不存在......
CREATE PROCEDURE GetPrice
@Region int = null
,@Store int = null
AS
SELECT
Product
,Region
,Store
,Price
FROM (SELECT
Product
,Region AS Region
,Store As Store
,Price
,Row_Number() OVER(PARTITION BY Product ORDER BY SortBy,Product,Region,Store,Price) AS RowNumber
FROM (SELECT 1 AS SortBy,* FROM Prices WHERE (Region = @Region OR @Region IS NULL) AND (Store = @Store OR @Store IS NULL)
UNION
SELECT 2 AS SortBy,* FROM Prices WHERE (Region = @Region OR @Region IS NULL)
UNION
SELECT 3 AS SortBy,* FROM Prices
) Prices
) dt
WHERE RowNumber=1
ORDER BY Product
GO
答案 1 :(得分:2)
SELECT COALESCE(st.Price, rg.Price, gn.Price) AS Price
FROM dbo.Prices gn /*General price*/
LEFT OUTER JOIN dbo.Prices rg /*Regional price*/
ON rg.Product = @Product AND rg.Region = @Region AND rg.Store IS NULL
LEFT OUTER JOIN dbo.Prices st /*Store price*/
ON rg.Product = @Product AND rg.Region = @Region AND rg.Store = @Store
WHERE gn.Product = @Product
AND gn.Region IS NULL AND gn.Store IS NULL
这样,如果不是空的话,您将获得商店价格,如果不是空的话,您将获得区域价格,如果所有其他商品都失败,您将获得一般价格。
答案 2 :(得分:1)
我认为您的数据模型可能有点棘手。价格表是否仅为报告填充?我可能会查看我的表格,但如果我必须使用此设置,我会做这样的事情:
指定区域内的产品价格(非商店)。在接受区域作为参数的sproc中使用此选择。如果我做得对,它将返回区域价格(如果有的话)和产品价格(如果没有)。
选择产品,价格来自dbo.prices,其中(Region = @ region)或(区域为NULL且产品不在(从区域= @Region的价格中选择产品))
指定商店的产品价格。在接受存储作为参数的存储区中使用此选择。您还需要传入区域或从商店中找出它。如果我做得对,它将返回商店价格,如果有,那么他区域价格,然后是产品价格。
选择产品,价格来自dbo.prices,其中(store = @store)或(商店为NULL AND region = @Region且产品不在(从商店= @store的价格中选择产品)或(商店为NULL和区域)是NULL并且产品不在(从region = @Region的价格中选择产品))
要从多个地区或商店获取价格,只需多次执行上述某个sprocs(在循环或游标中)。
答案 3 :(得分:-1)
我想这一定必须有效(尽管没有试过):
select top 1 price
from prices
where product = @product
and isnull(region, @region) = @region
and isnull(store, @store) = @store
order by region desc, store desc
产品必须至少有1个价格记录。 ORDER BY .. DESC最后对原始NULL值进行排序。