试试这个:
/* DATASET MOCK-UP */
DECLARE @Data TABLE ( ID INT, CODE VARCHAR(10), NUMBER INT, BALANCE DECIMAL(18,2) );
INSERT INTO @Data ( ID, CODE, NUMBER, BALANCE ) VALUES
( 1, 'B0001', 122960 , 100.00 ),
( 2, 'B0001', 123168 , -100.00 ),
( 3, 'B0001', 121400 , 500.00 ),
( 4, 'T0001', 19755 , 50.00 ),
( 5, 'T0001', 19975 , -50.00 ),
( 6, 'T0001', 122202 , 50.00 ),
( 7, 'T0001', 122203 , 50.00 );
/*
Return records where combined balances equal 0 by adding the
current record's BALANCE against its previous (lag) or following (lead) balances.
*/
SELECT
ID, CODE, NUMBER, BALANCE, ( BALANCE + LAG_BALANCE ) AS LAG_BALANCE, ( BALANCE + LEAD_BALANCE ) AS LEAD_BALANCE
FROM (
SELECT
ID,
CODE,
NUMBER,
BALANCE,
LAG ( BALANCE, 1, 0 ) OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS LAG_BALANCE,
LEAD ( BALANCE, 1, 0 ) OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS LEAD_BALANCE
FROM @Data
) AS Results
WHERE
BALANCE + LAG_BALANCE = 0
OR
BALANCE + LEAD_BALANCE = 0
ORDER BY
ID;
返回
+----+-------+--------+---------+-------------+--------------+
| ID | CODE | NUMBER | BALANCE | LAG_BALANCE | LEAD_BALANCE |
+----+-------+--------+---------+-------------+--------------+
| 1 | B0001 | 122960 | 100.00 | 100.00 | 0.00 |
| 2 | B0001 | 123168 | -100.00 | 0.00 | 400.00 |
| 4 | T0001 | 19755 | 50.00 | 550.00 | 0.00 |
| 5 | T0001 | 19975 | -50.00 | 0.00 | 0.00 |
| 6 | T0001 | 122202 | 50.00 | 0.00 | 100.00 |
+----+-------+--------+---------+-------------+--------------+
更新:
我只想要可以取消它们的 NUMBER 值。对于T0001,它返回哪个数字来取消负值并不重要,只要它只返回一对值。例如,对于 T0001,它可以返回第 4 行和第 5 行、第 5 行和第 6 行或第 5 行和第 7 行。它们都是有效的,但我只想要其中一个。
此编辑会为每个符合“归零”条件的 CODE 返回一个 NUMBER:
SELECT
CODE, MIN ( NUMBER ) AS MIN_NUMBER
FROM (
SELECT
ID,
CODE,
NUMBER,
BALANCE,
LAG ( BALANCE, 1, 0 ) OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS LAG_BALANCE,
LEAD ( BALANCE, 1, 0 ) OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS LEAD_BALANCE
FROM @Data
) AS Results
WHERE
BALANCE + LAG_BALANCE = 0
OR
BALANCE + LEAD_BALANCE = 0
GROUP BY
CODE
ORDER BY
CODE;
返回
+-------+------------+
| CODE | MIN_NUMBER |
+-------+------------+
| B0001 | 122960 |
| T0001 | 19755 |
+-------+------------+
更新 #2:
/*
Return the first TWO rows for a CODE with BALANCEs that zero-out each other.
*/
SELECT
ID, CODE, NUMBER, BALANCE, ( BALANCE + LAG_BALANCE ) AS LAG_BALANCE, ( BALANCE + LEAD_BALANCE ) AS LEAD_BALANCE
FROM (
SELECT
ID,
CODE,
NUMBER,
BALANCE,
LAG ( BALANCE, 1, 0 ) OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS LAG_BALANCE,
LEAD ( BALANCE, 1, 0 ) OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS LEAD_BALANCE,
ROW_NUMBER() OVER ( PARTITION BY CODE ORDER BY CODE, ID ) AS CODE_ROW
FROM @Data
) AS Results
WHERE
CODE_ROW <= 2
AND ( BALANCE + LAG_BALANCE = 0 OR BALANCE + LEAD_BALANCE = 0 )
ORDER BY
ID;
返回
+----+-------+--------+---------+-------------+--------------+
| ID | CODE | NUMBER | BALANCE | LAG_BALANCE | LEAD_BALANCE |
+----+-------+--------+---------+-------------+--------------+
| 1 | B0001 | 122960 | 100.00 | 100.00 | 0.00 |
| 2 | B0001 | 123168 | -100.00 | 0.00 | 400.00 |
| 4 | T0001 | 19755 | 50.00 | 50.00 | 0.00 |
| 5 | T0001 | 19975 | -50.00 | 0.00 | 0.00 |
+----+-------+--------+---------+-------------+--------------+