Ich habe zwei Tabellen. Einer steht für noch offene Rechnungen (Tabelle #OPEN
) und der andere für verfügbares Geld (Tabelle #overpay
). Beide haben eine Spalte USERID
, mit denen sie verbunden werden:Wie zwei Tabellen zu verbinden, aber jede Zeile nur einmal verwenden
CREATE TABLE #OVERPAY(OID INT, USERID CHAR(1), Rest INT)
CREATE TABLE #OPEN(IID INT, USERID CHAR(1), Amt INT, OpenROW INT)
Die Tabelle hat eine Spalte #Entfernen OpenRow
durch welche die offenen Mengen bestellt werden (pro Nutzer). Ich möchte Einträge aus der Tabelle kartieren #OVERPAY
auf Einträge in der Tabelle #OPEN
auf folgende Weise:
- Ein Eintrag wird abgebildet, wenn # OVERPAY.Rest> = # OPEN.AMT
- Kleinere Werte in #Entfernen. OpenRow erste abgebildet bekommen können
- Jeder Eintrag in #OVERPAY nur einmal verwendet werden
- Jeder Eintrag in #Entfernen kann nur einmal verwendet werden
Die letzten beiden Punkte in dieser Liste sind, was gibt mir ein Kopfschmerzen.
Dies sind einige verspottet Daten:
OID USERID REST
--------------------
1 'A' 10
2 'A' 15
3 'F' 5
4 'H' 20
5 'H' 5
INSERT INTO #OVERPAY(OID, USERID, Rest)
VALUES (1, 'A', 10), (2, 'A', 15), (3, 'F', 5),
(4, 'H', 20), (5, 'H', 5)
OID USERID Amt OpenRow
-----------------------------
1 'A' 10 1
2 'A' 10 2
3 'A' 15 3
4 'F' 5 1
5 'H' 15 1
6 'H' 10 2
7 'P' 33 1
INSERT INTO #OPEN(IID, USERID, Amt, OpenROW)
VALUES (1, 'A', 10, 1), (2, 'A', 10, 2),
(3, 'A', 15, 3), (4, 'F', 5, 1),
(5, 'H', 15, 1), (6, 'H', 10, 2),
(7, 'P', 33, 1)
Das gewünschte Ergebnis wäre:
OID IID
----------
1 1
2 2
3 4
4 5
Ich weiß, wie ich es mit einem CURSOR
tun könnte:
CREATE TABLE #map (OID INT, IID INT)
CREATE TABLE #usedIID(IID INT)
DECLARE @OID INT, @USERID CHAR(1), @Rest INT
DECLARE ov_cursor CURSOR FOR
SELECT OID, USERID, REST
FROM #OVERPAY
OPEN ov_cursor
FETCH NEXT FROM ov_cursor INTO @OID, @USERID, @REST
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @IID INT
INSERT INTO #map (OID, IID)
OUTPUT inserted.IID INTO #usedIID (IID)
SELECT TOP 1 @OID, o.IID
FROM #OPEN o
LEFT JOIN #usedIID u ON u.IID = o.IID
WHERE o.USERID = @USERID AND o.Amt <= @REST AND u.IID IS NULL
FETCH NEXT FROM ov_cursor INTO @OID, @USERID, @REST
END
CLOSE ov_cursor
DEALLOCATE ov_cursor
Aber da Das ist schrecklich in Bezug auf die Leistung (Ich arbeite mit einer riesigen Menge von Daten) Ich suche nach einer Option zu tun es ohne
Looping YES! Das scheint genau zu sein, wonach ich suche. Ich werde es in meinem realen Szenario ausprobieren und danach zurückkommen. Vielen Dank! –
Es funktioniert wie ein Zauber. Sehr schöne Lösung! –
Und nette Frage. – Serg