I'm sorry, I misread the lack of the Balance column. Right now, you´re using a triangular join which can be slower than a well written cursor. There's a technique called Quirky Update that is very fast and might help you if you have the correct conditions. Read this article and understand it before using it in production: http://www.sqlservercentral.com/articles/T-SQL/68467/
Be sure to follow the rules and the solution might come easily.
CREATE TABLE accounts(
AcctID INT,
TranSeq INT,
TranDate DATE,
Amount DECIMAL(18,4),
Balance DECIMAL(18,4)
CONSTRAINT pkAccounts PRIMARY KEY (AcctID,TranSeq));
GO
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(3,1,'04/24/2014',216.00, NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(3,2,'05/19/2014',-83.18,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(3,3,'05/19/2014',-109.90,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(3,4,'05/19/2014',-1.70,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(3,5,'03/17/2015',-21.22,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(3,6,'05/21/2015',-21.22,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(2,1,'08/08/2014',369.00, NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(2,2,'09/18/2014',-195.34,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(2,3,'10/16/2014',-173.66,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(2,4,'05/12/2015',-112.75,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(2,5,'06/08/2015',-173.66,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,1,'04/03/2014',223.00, NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,2,'04/03/2014',129.00, NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,3,'07/08/2014',-90.00,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,4,'07/08/2014',-73.00,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,5,'07/08/2014',-129.00,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,6,'08/07/2014',-58.80,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,7,'08/07/2014',-69.09,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,8,'11/26/2014',67.89 ,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,9,'12/30/2014',-67.89,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,10,'12/31/2014',67.89 ,NULL);
INSERT INTO accounts(AcctID, TranSeq,tranDate,Amount, Balance) VALUES(1,11,'05/29/2015',-67.89,NULL);
DECLARE @AcctID int,
@TranSeq int,
@Balance decimal(18, 4) = 0
--Quirky Update
UPDATE a
SET @Balance = Balance = Amount + CASE WHEN AcctID = @AcctID THEN @Balance ELSE 0 END,
@AcctID = AcctID
FROM accounts a WITH (TABLOCKX)
OPTION (MAXDOP 1);
SELECT * FROM accounts;
--Start of last credit
WITH MaxPositives AS(
SELECT AcctID,
MAX(TranDate) MaxTranDate
FROM accounts
WHERE Balance >= 0
GROUP BY AcctID
)
SELECT AcctID,
MIN(TranDate) CreditDate
FROM accounts a
WHERE EXISTS( SELECT *
FROM MaxPositives m
WHERE a.AcctID = m.AcctID
AND a.TranDate > m.MaxTranDate)
GROUP BY AcctId
ORDER BY AcctId;
WITH MaxPositives AS(
SELECT AcctID,
MAX(TranDate) MaxTranDate
FROM accounts
WHERE Balance >= 0
GROUP BY AcctID
),
RowNums AS(
SELECT *,
ROW_NUMBER() OVER( PARTITION BY AcctID ORDER BY TranDate) rn
FROM accounts a
WHERE EXISTS( SELECT *
FROM MaxPositives m
WHERE a.AcctID = m.AcctID
AND a.TranDate > m.MaxTranDate)
)
SELECT AcctID, TranSeq,tranDate,Amount, Balance
FROM RowNums
WHERE rn = 1
ORDER BY AcctId;
GO
DROP TABLE accounts