SQL NOT IN子查询?

时间:2013-01-18 15:57:46

标签: sql sql-server tsql sql-server-2000 subquery

所以我为同事写了以下查询(见下文):

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_ID。因此,例如,您可以为支票号20001设置三行,所有行都有不同的tender_ID。

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

需要更新,以便如果支票编号的投标ID为5,14,4,9,15,16,则删除该支票编号的所有实例。我知道这很可能是一个子查询,但是我整个上午一直在反对它而不能弄明白。 :(

3 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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 :(得分: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))