2013-01-18 160 views
1

所以我有以下查询(见下文),我写了一个同事:SQL不在子查询中?

SELECT 
     t.tender_id as "Tender ID", 
     t.check_number as "Check Number", 
     t.check_type_id as "Check Type", 
     t.server_id as "Server ID", 
     t.cashier_id as "Cashier ID", 
     t.terminal_id as "Terminal ID", 
     t.tendered_date_time as "Tendered Date and Time", 
     t.tender_amount as "Tender Amount", 
     t.change_amount as "Change Amount", 
     g.account_name as "Account Name", 
     g.account_number as "Account Number" 
FROM CheckTender AS t 
INNER JOIN AcountActivity AS g 
     ON t.check_number = g.check_number 
WHERE t.tender_id NOT in (5,14,4,9,15,16); 

支票号码可以有多个tender_IDs。因此,例如,您可以为检查号码20001设置三行,所有这些行都有不同的tender_ID。

最初,他只是想要删除tender_id为5,14,4,9,15,16的任何条目。但是后来我们发现我们需要修改哪些标准。

它需要更新,以便如果支票号码的投标ID为5,14,4,9,15,16,该支票号码的所有实例都将被删除。我知道这很可能是一个子查询,但我一直在头脑中一直在打我的头,而没有弄清楚。 :(

+2

http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join -is-null-sql-server/ –

+0

因此,找到属于这些投标ID的支票号码,并忽略这些支票号码。 – Kermit

+0

@marc_s SQL Server 2000 – Oryx

回答

3

您可以使用EXISTS此:

SELECT 
     t.tender_id as "Tender ID", 
     t.check_number as "Check Number", 
     t.check_type_id as "Check Type", 
     t.server_id as "Server ID", 
     t.cashier_id as "Cashier ID", 
     t.terminal_id as "Terminal ID", 
     t.tendered_date_time as "Tendered Date and Time", 
     t.tender_amount as "Tender Amount", 
     t.change_amount as "Change Amount", 
     g.account_name as "Account Name", 
     g.account_number as "Account Number" 
FROM CheckTender AS t 
INNER JOIN AcountActivity AS g 
     ON t.check_number = g.check_number 
WHERE NOT EXISTS ( SELECT * FROM CheckTender WHERE check_number = t.check_number 
        AND tender_id in (5,14,4,9,15,16)) 
+0

非常感谢! – Oryx

2

像这样(未经)

SELECT 
     t.tender_id as "Tender ID", 
     t.check_number as "Check Number", 
     t.check_type_id as "Check Type", 
     t.server_id as "Server ID", 
     t.cashier_id as "Cashier ID", 
     t.terminal_id as "Terminal ID", 
     t.tendered_date_time as "Tendered Date and Time", 
     t.tender_amount as "Tender Amount", 
     t.change_amount as "Change Amount", 
     g.account_name as "Account Name", 
     g.account_number as "Account Number" 
FROM CheckTender AS t 
INNER JOIN AcountActivity AS g 
     ON t.check_number = g.check_number 
LEFT JOIN (SELECT check_number FROM CheckTender WHERE tender_id in (5,14,4,9,15,16)) t2 on t.tender_id = t2.tender_id 
WHERE t2.tender_id is null 
2

这里是一个办法与窗口函数来做到这一点:?

select * 
from (SELECT 
      t.tender_id as "Tender ID", 
      t.check_number as "Check Number", 
      t.check_type_id as "Check Type", 
      t.server_id as "Server ID", 
      t.cashier_id as "Cashier ID", 
      t.terminal_id as "Terminal ID", 
      t.tendered_date_time as "Tendered Date and Time", 
      t.tender_amount as "Tender Amount", 
      t.change_amount as "Change Amount", 
      g.account_name as "Account Name", 
      g.account_number as "Account Number", 
      MAX(case when t.tender_id in (5,14,4,9,15,16) then 1 else 0 end) over (partition by t.check_number) as HasBadTender 
     FROM CheckTender AS t 
     INNER JOIN AcountActivity AS g 
       ON t.check_number = g.check_number 
    ) t 
where HasBadTender = 0 

这适用于SQL Server 2005及更高版本对于早期版本,您需要某种形式的连接或更正兴高采烈的子查询。

你原来的细微变化where子句也可以工作:

WHERE t.check_number not in (select check_number from CheckTender where tender in (5,14,4,9,15,16))