我有一个包含两列的表:intGroupID、decAmount
如果对于每个正 (+) decAmount,有一个相等和相反的负 (-) decAmount,我想要一个基本上可以返回 intGroupID 作为结果的查询。
因此 (id=1,amount=1.0),(1,2.0),(1,-1.0),(1,-2.0) 的表将返回 1 的 intGroupID,因为对于每个正数都存在一个负数要匹配的号码。
到目前为止我所知道的是必须有相等数量的 decAmount(所以我强制执行 count(*) % 2 = 0)并且所有行的总和必须 = 0.0。但是,通过该逻辑得到的一些情况是:
身份证 | 数量
- 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,行数为偶数,但正面与负面之间不存在一对一的关系。我需要一个查询,它基本上可以告诉我每个正数是否有负数,而无需重用任何行。
我尝试计算数字的不同绝对值并强制它小于所有行的计数,但它并没有捕获所有内容。
我到目前为止的代码:
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
我认为可能有更好的方法来检查这个表,可能是通过找到对并将它们从表中删除,并在没有更多正/负匹配时查看表中是否还有任何东西,但我宁愿不必使用递归/游标。