У меня очень специфическая проблема c - я пытаюсь сопоставить вейлы - один ко многим. Я довольно плохо знаком с курсорами, поэтому не могу решить свою собственную проблему.
Немного понимания - у меня есть 2 таблицы - одна с положительными значениями и одна с отрицательными. Я должен сопоставить сумму отрицательных значений положительному, и разница не может быть больше +/- 5. Примеры таблиц ниже:
TABLE1
-----------
200 | abc
125 | abc
TABLE2
----------
-50 | abc
-50 | abc
-75 | abc
-100 | abc
-125 | abc
Я хочу попытаться суммировать отрицательные значения от TABLE2
независимо от того, порядка, чтобы попытаться сопоставить положительное значение от TABLE1
Проблема в том, что нет определенного порядка c, в котором мой курсор должен перемещаться между записями, и я использую CURSOR
без SCROLL
вариант, как я никогда не использовал его раньше.
Как бы я go написал о коде, который бы проверял все возможные перестановки или, по крайней мере, до точки, где он получал совпадение, в этом случае записывает 1,2 и 4 из TABLE2
суммирует до записи из TABLE1
или записи 3 и 5 из TABLE2
суммируют до записи из TABLE1
.
Возможно ли это?
Дополнительно - Я должен подчеркнуть, что TABLE1
будет иметь больше записей, чем я использовал в примере, и что если я сопоставлю значения 1,2 и 4 из TABLE2
, я не смогу снова использовать эти значения при следующем сопоставлении l oop для следующей записи в TABLE1
, в этом случае можно использовать только значение 5 из TABLE2
.
Это код, который я должен иметь до сих пор, и я не думаю, что это правильный.
DECLARE @idPos as int
DECLARE @zuonrPos as varchar(18)
DECLARE @belnrPos as varchar(10)
DECLARE @dmbtrPos as decimal(15,2)
DECLARE @idNeg as int
DECLARE @zuonrNeg as varchar(18)
DECLARE @belnrNeg as varchar(10)
DECLARE @dmbtrNeg as decimal(15,2)
DECLARE @SumVal as numeric(15,2) = 0
DECLARE @outerLoop as int
DECLARE @innerLoop as int
IF OBJECT_ID('tempdb..#Report') IS NOT NULL DROP TABLE #Report
CREATE TABLE #Report (
ZUONR varchar(18),
BELNRPos varchar(10),
SumPosVal decimal(15,2),
BELNRNeg varchar(10),
SumNegVal decimal(15,2)
)
IF OBJECT_ID('tempdb..#OpenItems') IS NOT NULL DROP TABLE #OpenItems
SELECT DISTINCT ROW_NUMBER() OVER (ORDER BY MN.ZUONR) AS ID, MN.ZUONR, MN.BELNR, MN.DMBTR, NULL as Marker INTO #OpenItems
FROM dbo.FIS_BELEG MN WITH (NOLOCK)
WHERE MN.ZUONR IS NOT NULL AND MN.HKONT IN ('00123','00122') AND (MN.AUGBL IS NULL OR MN.AUGBL = '') AND MN.DMBTR > 0
ORDER BY MN.ZUONR, MN.DMBTR
IF OBJECT_ID('tempdb..#NegValues') IS NOT NULL DROP TABLE #NegValues
SELECT DISTINCT ROW_NUMBER() OVER (ORDER BY MN.ZUONR) AS ID, MN.ZUONR, MN.BELNR, MN.DMBTR, NULL as Marker INTO #NegValues
FROM dbo.FIS_BELEG MN WITH (NOLOCK)
WHERE MN.ZUONR IS NOT NULL AND MN.HKONT IN ('00123','00122') AND (MN.AUGBL IS NULL OR MN.AUGBL = '') AND MN.DMBTR < 0
ORDER BY MN.ZUONR, MN.DMBTR
DECLARE PosCurs CURSOR FOR
SELECT DISTINCT ID, ZUONR, BELNR, DMBTR FROM #OpenItems
WHERE Marker IS NULL AND ZUONR = @zuonrPos
OPEN PosCurs
FETCH NEXT FROM PosCurs INTO @idPos, @zuonrPos, @belnrPos, @dmbtrPos
SET @outerLoop = @@FETCH_STATUS
WHILE @outerLoop = 0
BEGIN
DECLARE NegCurs CURSOR FOR
SELECT DISTINCT ID, ZUONR, BELNR, DMBTR FROM #NegValues
WHERE Marker IS NULL
OPEN NegCurs
FETCH NEXT FROM NegCurs INTO @idNeg, @zuonrNeg, @belnrNeg, @dmbtrNeg
SET @innerLoop = @@FETCH_STATUS
WHILE @innerLoop = 0 AND (@dmbtrPos BETWEEN (@SumVal - 5) AND (@SumVal + 5)) AND (@SumVal * 0.01) < 5
BEGIN
SET @SumVal = @SumVal + ABS(@dmbtrNeg)
INSERT INTO #Report VALUES (@zuonrPos, @belnrPos, @dmbtrPos, @belnrNeg, @dmbtrNeg)
UPDATE #OpenItems
SET Marker = 1 WHERE ZUONR = @zuonrPos AND BELNR = @belnrPos
UPDATE #NegValues
SET Marker = 1 WHERE ZUONR = @zuonrNeg AND BELNR = @belnrNeg
FETCH NEXT FROM NegCurs INTO @idNeg, @zuonrNeg, @belnrNeg, @dmbtrNeg
END
CLOSE NegCurs
DEALLOCATE NegCurs
SET @SumVal = 0
FETCH NEXT FROM PosCurs INTO @idPos, @zuonrPos, @belnrPos, @dmbtrPos
END
CLOSE PosCurs
DEALLOCATE PosCurs
Я уже некоторое время просматриваю inte rnet, чтобы попытаться найти ответ, однако я с треском провалился. Есть идеи?