数据库设计 - 覆盖值

时间:2016-08-13 17:06:28

标签: sql sql-server database-design

我试图确定我目前的设计是否最有意义。我有一个定价表,它将始终具有给定产品(ProductId)的默认值。根据多种环境,价格可能会被覆盖。

鉴于此表:

table & data

我想根据给定的城市,县,州或默认价格获得适当的价格。这有点人为,因为Type和Priority代表相同的东西,可能仅限于int和索引(不需要字符串)。我使用INT是因为它允许我对从内部查询的TOP中选择哪一个进行排序和优先级排序。使用此SQL:

SELECT DISTINCT ProductId, prices.Price
FROM [CCC].[Prices] p CROSS APPLY
(
   SELECT TOP 1 Price 
   FROM [CCC].[Prices] p2 
   WHERE p.ProductId = p2.ProductId 
     AND (Type = 'Default' 
       OR (Type = 'City' AND TypeId = 553) 
       OR (Type = 'State' AND TypeId = '4'))
   ORDER BY [Priority] DESC
) prices

准确地告诉我我正在寻找的东西:

enter image description here

我正在考虑的两种方法是:

所有应用程序代码(所有值都可用,然后基于空值找到最合适的价格。

在SQL中(如上所示),取desc中按优先级排序的最高值 并且在SQL中使用交叉应用来获取所有价格(相对于单个记录)。 Coalesce(解决已发布的答案)也是一种解决方案,但合并可能是我过去发现的扩展。我更喜欢这个版本。

我应该考虑其他方法或模式吗?

2 个答案:

答案 0 :(得分:0)

如果您要使用cross apply,可以在SQL Server中完成工作。这样的事情是一种方法:

select t.*, p.price
from t cross join
     (select
      from pricing p
      where p.productid = t.productid and
            (p.city = t.city or
             p.county = t.county and p.city is null or
             p.state = t.state and p.county is null and t.county is null or
             p.state is null
            )
      order by (case when p.city is not null then 1
                     when p.county is not null then 2
                     when p.state is not null then 3
                     else 4
                end)
     ) p

答案 1 :(得分:0)

如果模式city,county,state,default是fix,那么你可以通过外连接和coalesce来完成它,如下所示:

select t.*, coalesce(city.price, county.price, state.price, defaulttab.price) as price
 from t left outer join citytab as city  t.productid = city.productid
                                          and on t.city = city.city 
        left outer join countytab as county  on t.productid = county.productid
                                          and t.county = county.county
        left outer join statetab as state on  t.productid = state.productid
                                          and t.state = state.state
        join defautlttab on t.productid = defaulttab.productid