2017-10-05 139 views
0

我有一张表,我试图找到一组特定的记录。下面是我的表看起来像......查询数据库中没有第二条记录的记录取消它

tblA 

ID    VouchID   Action  Amount   
1    177-17   Add   700 
2    177-17   Update  1 
3    198-01   Add   600 
4    198-01   Update  620 

所以会发生什么在这里,是,如果一个记录被取消/删除,行动将“升级”和金额将被更新为1。换句话说, VouchID = 177-17,不会被计算/在此查询中被选中...

我希望在这里做的只是选择记录,没有相应的更新记录与金额= 1

Select distinct vouchID where Action='add' 

但是,这个查询没有考虑VoucherID的'更新'行为。更新操作可以在两个实例中应用,在VouchID 177-17中,amount = 1 on action ='update',这意味着ADD操作不计数,就好像我们一起删除了记录(它只是用于保持记录中)。在VoucherID = 198-01的情况下,更新行和金额= 620的另一更新意味着金额已被更新20到620,该记录我希望能够在我的末尾看到reuslt

期望的最终结果从上面的表格:

ID    VouchID   Action  Amount 
3    198-01   Add   600 

回答

2

你可以使用LEAD(SQL服务器2012及以上):

WITH cte AS (
    SELECT *, LEAD(Amount) OVER(PARTITION BY VouchID ORDER BY ID) AS next_amount 
    FROM table 
) 
SELECT * 
FROM cte 
WHERE (next_amount <> 1 OR next_amount IS NULL) AND Action='add'; 

编辑

非递归CTE可以用简单的子查询始终代替:

SELECT * 
FROM (SELECT *, 
     LEAD(Amount) OVER(PARTITION BY VouchID ORDER BY ID) AS next_amount 
     FROM table) sub 
WHERE (next_amount <> 1 OR next_amount IS NULL) AND Action='add'; 

编辑:

使用EXISTS

SELECT * 
FROM table t1 
WHERE Action='add' 
    AND NOT EXISTS (SELECT TOP 1 
        FROM table t2 
        WHERE t1.VouchId = t2.VouchId 
        AND Action='Update' 
        AND Amount = 1 
        ORDER BY ID ASC); 
+0

有没有什么办法,因为我必须做的与另一个表 – BobSki

+0

@BobSki当然你加入我能做到这一点没有CTE根本不需要CTE – lad2025

+0

谢谢当我使用LEAD SQL服务器告诉我LEAD不是一个公认的内置函数名:( – BobSki

1

您是否使用SQL Server 2008或更好?如果你是,我会尝试这样的:

SELECT 
    ID, vouchID, Action, Amount  
FROM tblA s 
WHERE 
    Action='add' 
    AND NOT EXISTS(Select 1 from tblA l where l.vouchID = s.vouchID and l.Action = 'Update' and l.Amount = 1); 
+0

谢谢............... – BobSki

2

就是我希望做的,是唯一的选择记录,即没有与金额= 1

一个 相应的更新记录

似乎很容易用NOT EXISTS():

Select distinct vouchID FROM MyTable t1 where Action='add' 
AND NOT EXISTS(SELECT * FROM MyTable t2 
    WHERE Action='Update' 
    AND Amount=1 
    AND t2.VouchId=t1.VouchId 
+0

谢谢.......... – BobSki

相关问题