Configurar
Eu configurei um exemplo em rextester e dbfiddle .
Cenário
Lista de preços : É a lista de preços dos produtos, um produto pode ter mais de um preço ativo, mesmo um preço futuro.
+---------+-------+------------+--------+--------+
| 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 |
+---------+-------+------------+--------+--------+
Encomendas As encomendas pendentes têm um preço e uma data de encomenda
+---------+------------+-------+--------+
| 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 |
+---------+------------+-------+--------+
Sempre que adicionamos um novo preço na lista, devemos atualizar as linhas afetadas de pedidos pendentes.
Por exemplo, se adicionarmos:
+---------+-------+------------+--------+--------+
| product | price | date_price | base | active |
+---------+-------+------------+--------+--------+
| 0125 | 105 | 21.02.2017 | 1300 | 1 |
| 1200 | 155 | 21.02.2017 | 1400 | 1 |
+---------+-------+------------+--------+--------+
A nova lista de preços deve ser:
+---------+------------+-------+--------+
| 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 |
+---------+------------+-------+--------+
Gostaria de atualizar os registros afetados usando uma única consulta.
Por existir outro preço a partir de 27.02.2017, os pedidos de 28.02.2017 não são afetados pelo preço inserido.
Processo real
Até agora, uso uma subconsulta que busca a primeira data que corresponde na tabela da lista de preços, mas agora preciso atualizar o base
campo também. (E mais dois ou três campos) e gostaria de evitar usar duas ou mais subconsultas.
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
Por favor, sinta-se à vontade para corrigir meu texto, eu sei que minha gramática inglesa não é boa o suficiente.
Eu usei seu código dbfiddler na seguinte solução que usa CROSS APPLY
Em primeiro lugar, quero agradecer a @ScottHodgin por seu trabalho para resolver minha pergunta.
Embora sua resposta tenha resolvido corretamente o problema, ela atualiza todos os pedidos ativos de um determinado produto. E eu queria encontrar uma solução que atualizasse apenas os pedidos afetados pela nova data da lista de preços.
Como esse procedimento é executado dentro de uma trigger, preciso gerar uma lista de intervalos de datas para comparar com a data dos pedidos.
Estou adicionando um dia a 'next_date' se não houver próximo registro PriceList, apenas para comparar com
<=
.Uma vez resolvido o problema do intervalo de datas, só preciso atualizar os pedidos dentro desse intervalo.
Após inserir dois registros:
Esse é o resultado final:
Se alguém estiver interessado, eu configurei um exemplo dbfiddle .