设置
我已经在rextester和dbfiddle上设置了一个示例。
设想
Price list : 产品价格表,一个产品可以有多个有效价格,甚至是未来价格。
+---------+-------+------------+--------+--------+
| product | price | date_price | base | active |
+---------+-------+------------+--------+--------+
| 0125 | 90 | 01.01.2017 | 1200 | 0 |
| 0125 | 100 | 25.01.2017 | 1000 | 1 |
| 0125 | 110 | 27.02.2017 | 500 | 1 |
+---------+-------+------------+--------+--------+
| 1200 | 140 | 01.01.2017 | 2000 | 0 |
| 1200 | 150 | 01.02.2017 | 1500 | 1 |
| 1200 | 160 | 27.02.2017 | 1000 | 1 |
+---------+-------+------------+--------+--------+
订单挂单有价格和订单日期
+---------+------------+-------+--------+
| product | order_date | price | base |
+---------+------------+-------+--------+
| 0125 | 19.02.2017 | 100 | 1000 |
| 0125 | 20.02.2017 | 100 | 1000 |
| 0125 | 21.02.2017 | 100 | 1000 |
| 0125 | 22.02.2017 | 100 | 1000 |
| 0125 | 23.02.2017 | 100 | 1000 |
| 0125 | 28.02.2017 | 110 | 500 |
+---------+------------+-------+--------+
| 1200 | 19.02.2017 | 150 | 1500 |
| 1200 | 20.02.2017 | 150 | 1500 |
| 1200 | 21.02.2017 | 150 | 1500 |
| 1200 | 22.02.2017 | 150 | 1500 |
| 1200 | 23.02.2017 | 150 | 1500 |
| 1200 | 28.02.2017 | 160 | 1000 |
+---------+------------+-------+--------+
每次我们在列表中添加新价格时,我们都必须更新受影响的挂单行。
例如,如果我们添加:
+---------+-------+------------+--------+--------+
| product | price | date_price | base | active |
+---------+-------+------------+--------+--------+
| 0125 | 105 | 21.02.2017 | 1300 | 1 |
| 1200 | 155 | 21.02.2017 | 1400 | 1 |
+---------+-------+------------+--------+--------+
新价目表必须是:
+---------+------------+-------+--------+
| product | order_date | price | base |
+---------+------------+-------+--------+
| 0125 | 19.02.2017 | 100 | 1000 |
| 0125 | 20.02.2017 | 100 | 1000 |
| 0125 | 21.02.2017 | 105 | 1300 | *
| 0125 | 22.02.2017 | 105 | 1300 | * Affected rows
| 0125 | 23.02.2017 | 105 | 1300 | *
| 0125 | 28.02.2017 | 110 | 500 |
+---------+------------+-------+--------+
| 1200 | 19.02.2017 | 150 | 1500 |
| 1200 | 20.02.2017 | 150 | 1500 |
| 1200 | 21.02.2017 | 150 | 1500 | *
| 1200 | 22.02.2017 | 150 | 1500 | * Affectd rows between 21.02.2017 and 27.02.2017
| 1200 | 23.02.2017 | 150 | 1500 | *
| 1200 | 28.02.2017 | 160 | 1000 |
+---------+------------+-------+--------+
我想使用单个查询更新受影响的记录。
由于还有另一个价格从 27.02.2017 开始,因此 28.02.2017 的订单不受插入价格的影响。
实际过程
到目前为止,我使用子查询来搜索价格列表中匹配的第一个日期,但现在我也需要更新base
字段。(以及两个或三个以上的字段)并且我想避免使用两个或多个子查询。
update @orders
set price = (select top 1 pl.price
from @price_list pl
where pl.product = o.product
and pl.date_price <= o.order_date
and active = 1
order by pl.date_price desc),
base = (select top 1 pl.base
from @price_list pl
where pl.product = o.product
and pl.date_price <= o.order_date
and active = 1
order by pl.date_price desc)
from @orders o
where o.product in ('0125', '1200'); --<<< select distinct product from inserted
请随时纠正我的文字,我知道我的英语语法不够好。
我在以下使用CROSS APPLY的解决方案中使用了 dbfiddler 代码
首先,我要感谢@ScottHodgin 为解决我的问题所做的工作。
尽管他的回答正确地解决了问题,但它更新了特定产品的所有有效订单。我想找到一种解决方案,只更新受新价目表日期影响的订单。
由于此过程是在触发器内执行的,因此我需要生成一个日期间隔列表以与订单日期进行比较。
如果没有下一个 PriceList 记录,我将在“下一个日期”中添加一天,只是为了与
<=
.一旦解决了日期范围的问题,我只需要更新这个范围内的订单。
插入两条记录后:
这是最终结果:
如果有人感兴趣,我已经设置了一个dbfiddle示例。