intGroupID、decAmount の 2 つの列を持つテーブルがあります。
基本的に、すべての正(+)のdecAmountに対して、等しい反対の負(-)のdecAmountがある場合、結果としてintGroupIDを返すことができるクエリが必要です。
したがって、(id=1,amount=1.0),(1,2.0),(1,-1.0),(1,-2.0) のテーブルは、1 の intGroupID を返します。これは、正の数ごとに負の数が存在するためです。一致する数。
これまでのところ、同じ数の decAmounts が必要であり (したがって、count(*) % 2 = 0 を強制する)、すべての行の合計が 0.0 でなければならないことがわかっています。ただし、そのロジックで得られるいくつかのケースは次のとおりです。
ID | 額
- 1 | 1.0
- 1 | -1.0
- 1 | 2.0
- 1 | -2.0
- 1 | 3.0
- 1 | 2.0
- 1 | -4.0
- 1 | -1.0
この合計は 0.0 で、行数は偶数ですが、正と負の 1 対 1 の関係はありません。行を再利用せずに、正の金額ごとに負の金額があるかどうかを基本的に教えてくれるクエリが必要です。
数値の個別の絶対値を数え、それがすべての行の数よりも少ないことを強制しようとしましたが、すべてをキャッチしているわけではありません。
私がこれまでに持っているコード:
DECLARE @tblTest TABLE(
intGroupID INT
,decAmount DECIMAL(19,2)
);
INSERT INTO @tblTest (intGroupID ,decAmount)
VALUES (1,-1.0),(1,1.0),(1,2.0),(1,-2.0),(1,3.0),(1,2.0),(1,-4.0),(1,-1.0);
DECLARE @intABSCount INT = 0
,@intFullCount INT = 0;
SELECT @intFullCount = COUNT(*) FROM @tblTest;
SELECT @intABSCount = COUNT(*) FROM (
SELECT DISTINCT ABS(decAmount) AS absCount FROM @tblTest GROUP BY ABS(decAmount)
) AS absCount
SELECT t1.intGroupID
FROM @tblTest AS t1
/* Make Sure Even Number Of Rows */
INNER JOIN
(SELECT COUNT(*) AS intCount FROM @tblTest
)
AS t2 ON t2.intCount % 2 = 0
/* Make Sure Sum = 0.0 */
INNER JOIN
(SELECT SUM(decAmount) AS decSum FROM @tblTest)
AS t3 ON decSum = 0.0
/* Make Sure Count of Absolute Values < Count of Values */
WHERE
@intABSCount < @intFullCount
GROUP BY t1.intGroupID
おそらくペアを見つけてテーブルから削除し、正/負の一致がなくなったらテーブルに何か残っているかどうかを確認することで、このテーブルを確認するより良い方法があると思いますが、そうする必要はありません。再帰/カーソルを使用します。