2013-01-18 191 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))