我有一个包含两列的表:intGroupID,decAmount
我希望有一个查询,基本上可以返回intGroupID作为结果,如果对于每个正(+)decAmount,有一个相等和相反的负( - )decAmount.
因此,(id = 1,amount = 1.0),(1,2.0),(1,-1.0),(1,-2.0)的表将返回intGroupID为1,因为对于每个正数,都存在负数要匹配的数字.
到目前为止我所知道的是必须有相同数量的decAmounts(所以我强制执行count(*)%2 = 0)并且所有行的总和必须= 0.0.但是,通过该逻辑获得的一些案例是:
ID | 量
它的总和为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
Run Code Online (Sandbox Code Playgroud)
我认为可能有更好的方法来检查这个表,可能是通过查找对并从表中删除它们,看看一旦没有更多的正/负匹配,表中是否还有任何东西,但我宁愿不必使用递归/游标.
天哪,我找到了比之前的答案更简单的方法。我希望我所有疯狂的编辑都能被保存下来供后代使用。
COUNT
仅当检测偶数个零时才需要通过聚合来检测均匀度。我假设 0 可能存在,并且它们应该出现偶数次。如果这不是问题,请将其删除,因为 0 始终会通过第一个测试。询问
WITH tt AS (
SELECT intGroupID,
CASE WHEN SUM(decAmount) > 0 OR COUNT(*) % 2 = 1 THEN 1 ELSE 0 END unequal
FROM @tblTest
GROUP BY intGroupID, ABS(decAmount)
)
SELECT tt.intGroupID,
CASE WHEN SUM(unequal) != 0 THEN 'not equal' ELSE 'equals' END [pair]
FROM tt
GROUP BY intGroupID;
Run Code Online (Sandbox Code Playgroud)
测试值
(1,-1.0),(1,1.0),(1,2),(1,-2), -- should work
(2,-1.0),(2,1.0),(2,2),(2,2), -- fail, two positive twos
(3,1.0),(3,1.0),(3,-1.0), -- fail two 1's , one -1
(4,1),(4,2),(4,-.5),(4,-2.5), -- fail: adds up the same sum, but different values
(5,1),(5,-1),(5,0),(5,0), -- work, test zeros
(6,1),(6,-1),(6,0), -- fail, test zeros
(7,1),(7,-1),(7,-1),(7,1),(7,1) -- fail, 3 x 1
Run Code Online (Sandbox Code Playgroud)
结果
A pairs
_ _____
1 equal
2 not equal
3 not equal
4 not equal
5 equal
6 not equal
7 not equal
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1611 次 |
最近记录: |