我的表格包含字段TransactionID
,Amount
和ParentTransactionID
可以取消交易,以便将amount
和ParentTransactionID
作为已取消TransactionID
的新条目发布。
让我们说一个交易
1 100 NULL
我取消了以上条目,它会像
2 -100 1
再次取消了上述交易,所以应该
3 100 2
当我拿到时,我应该得到记录3作为ID 1和2被取消。 结果应该是
3 100 2
如果我取消了第3个条目,则不会返回任何记录。
SELECT * FROM Transaction t
WHERE NOT EXISTS (SELECT TOP 1 NULL FROM Transaction pt
WHERE (pt.ParentTransactionID = t.TransactionID OR t.ParentTransactionID = pt.TransactionID)
AND ABS(t.Amount) = ABS(pt.Amount))
如果仅取消一级,则此方法有效。
答案 0 :(得分:1)
如果所有交易都被新交易设置的ParentTransactionId取消,它取消了它的交易,可以使用简单的LEFT JOIN
;
SELECT t1.* FROM Transactions t1
LEFT JOIN Transactions t2
ON t1.TransactionId = t2.ParentTransactionId
WHERE t2.TransactionId IS NULL;
t1
是我们目前正在查看的交易,t2
是可能取消的交易。如果没有取消交易(即TransactionId
t2
不存在),请返回该行。
我不确定你的最后一句话,If I cancelled the 3rd entry no records should return.
。如果不在表中添加新事务,您将如何取消#3?您可能还有一些其他条件可以取消您没有告诉我们的消息......?
编辑:由于您不希望取消交易(或者更确切地说取消奇数次数的交易),您需要一个相当复杂的递归查询来确定是否显示最后一笔交易;
WITH ChangeLog(TransactionID, Amount, ParentTransactionID,
IsCancel, OriginalTransactionID) AS
(
SELECT TransactionID, Amount, ParentTransactionID, 0, TransactionID
FROM Transactions WHERE ParentTransactionID IS NULL
UNION ALL
SELECT t.TransactionID, t.Amount, t.ParentTransactionID,
1-c.IsCancel, c.OriginalTransactionID
FROM Transactions t
JOIN ChangeLog c ON c.TransactionID = t.ParentTransactionID
)
SELECT c1.TransactionID, c1.Amount, c1.ParentTransactionID
FROM ChangeLog c1
LEFT JOIN ChangeLog c2
ON c1.TransactionID < c2.TransactionID
AND c1.OriginalTransactionID = c2.OriginalTransactionID
WHERE c2.TransactionID IS NULL AND c1.IsCancel=0
在具有3个事务的示例中,这将显示最后一行,但如果最后一行被取消,则不会返回任何内容。
由于SQLfiddle再次出现,here is a fiddle to test with。
即使有点难以以简单的方式做,也可以按顺序对查询进行简短说明;它定义了一个递归的“视图”,ChangeLog
跟踪取消和原始事务id从原始到系列中的最后一个事务(一系列是具有相同OriginalTransactionId的所有事务)。之后,它将ChangeLog
与自身连接以查找最后一个条目(即所有没有取消事务的事务)。如果系列中找到的最后一个条目不是取消(IsCancel
= 0),它将显示。