Installieren
Ich habe ein Beispiel für rextester und dbfiddle erstellt .
Szenario
Preisliste : Es ist die Preisliste für Produkte. Ein Produkt kann mehr als einen aktiven Preis haben, sogar einen zukünftigen Preis.
+---------+-------+------------+--------+--------+
| 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 |
+---------+-------+------------+--------+--------+
Bestellungen Ausstehende Bestellungen haben einen Preis und ein Bestelldatum
+---------+------------+-------+--------+
| 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 |
+---------+------------+-------+--------+
Jedes Mal, wenn wir der Liste einen neuen Preis hinzufügen, müssen wir die betroffenen Zeilen ausstehender Bestellungen aktualisieren.
Zum Beispiel, wenn wir hinzufügen:
+---------+-------+------------+--------+--------+
| product | price | date_price | base | active |
+---------+-------+------------+--------+--------+
| 0125 | 105 | 21.02.2017 | 1300 | 1 |
| 1200 | 155 | 21.02.2017 | 1400 | 1 |
+---------+-------+------------+--------+--------+
Die neue Preisliste muss lauten:
+---------+------------+-------+--------+
| 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 |
+---------+------------+-------+--------+
Ich möchte betroffene Datensätze mit einer einzigen Abfrage aktualisieren.
Da es einen weiteren Preis gibt, der am 27.02.2017 beginnt, sind Bestellungen vom 28.02.2017 vom eingefügten Preis nicht betroffen.
Tatsächlicher Prozess
Inzwischen verwende ich eine Unterabfrage, die nach dem ersten Datum sucht, das in der Preislistentabelle übereinstimmt, aber jetzt muss ich auch das base
Feld aktualisieren . (Und zwei oder drei weitere Felder) und ich möchte vermeiden, zwei oder mehr Unterabfragen zu verwenden.
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
Bitte zögern Sie nicht, meinen Text zu korrigieren. Ich weiß, dass meine englische Grammatik nicht gut genug ist.
quelle
Antworten:
Ich habe Ihren dbfiddler-Code in der folgenden Lösung verwendet, die CROSS APPLY verwendet
quelle
select price, base, date_price from inserted
Zunächst möchte ich @ScottHodgin für seine Arbeit zur Lösung meiner Frage danken.
Obwohl seine Antwort das Problem korrekt gelöst hat, werden alle aktiven Bestellungen für ein bestimmtes Produkt aktualisiert. Und ich wollte eine Lösung finden, die nur Bestellungen aktualisiert, die vom neuen Preislistendatum betroffen sind.
Da diese Prozedur innerhalb eines Triggers ausgeführt wird, muss ich eine Liste von Datumsintervallen erstellen, um sie mit dem Datum der Bestellungen zu vergleichen.
Ich füge 'next_date' einen Tag hinzu, wenn es keinen nächsten PriceList-Datensatz gibt, nur um ihn zu vergleichen
<=
.Sobald das Problem des Datumsbereichs gelöst ist, muss ich nur noch Bestellungen innerhalb dieses Bereichs aktualisieren.
Nach dem Einfügen von zwei Datensätzen:
Dies ist das Endergebnis:
Wenn jemand interessiert ist, habe ich ein dbfiddle- Beispiel eingerichtet.
quelle