SQL - 如何从where子句列表中返回不在表中的ID?

时间:2011-02-04 21:36:31

标签: sql db2

给出这样的查询:

select customerId
  from customer
 where customerId in (
          1, 2, 3
       )

我在where子句列表中有数百个ID;如何从where子句中的列表中返回不在表中的ID?

这是一个生产表,我只能运行select个查询。我只能运行select个查询;我无权创建任何表格。

6 个答案:

答案 0 :(得分:6)

您可以使用VALUES语句伪造SELECT中的表:

SELECT t1.customerId
FROM
  (VALUES (1), (2), (3), (4)) AS t1(customerId)
LEFT OUTER JOIN
  customer c
ON
  c.customerId = t1.customerId
AND
  c.customerId IS NULL

参考

答案 1 :(得分:4)

在DB2上有一种更简单的方法,使用VALUES动态构建表:

select 
   customerID
from 
   table(values (1),(2),(3)) as a (customerID)  
except 
select 
   customerID 
from 
   customers;

请注意,您需要在每个值周围加上括号,以确保每个值都是表结构中的“行”。

对于此示例,如果您的customers表具有customerIDs 1,2,3和4,则此查询将返回值4.

这应该适用于DB2 UDB for z / OS V8及更高版本。它将在DB2 for Linux / UNIX / Windows上运行。

答案 2 :(得分:3)

我将这些ID放入表格结构中,并将其与您的客户表格挂起。

select t.customerId
    from SomeTable t
        left join customer c
            on t.customerId = c.customerId
    where c.customerId is null

答案 3 :(得分:2)

对于大多数DBMS来说,

真正,野蛮的方法,这将有效(除了需要select..from dual的Oracle)。即使您无权访问创建/更新表,也只能SELECT

,这应该适用于DB2
select N1.N * 1000 + N2.N * 100 + N3.N * 10 + N4.N as NonExistentCustomerID
from (
    select 1 as N union all select 2 union all select 3 union all
    select 4 union all select 5 union all select 6 union all
    select 7 union all select 8 union all select 9 union all
    select 0) N1
cross join (
    select 1 as N union all select 2 union all select 3 union all
    select 4 union all select 5 union all select 6 union all
    select 7 union all select 8 union all select 9 union all
    select 0) N2
cross join (
    select 1 as N union all select 2 union all select 3 union all
    select 4 union all select 5 union all select 6 union all
    select 7 union all select 8 union all select 9 union all
    select 0) N3
cross join (
    select 1 as N union all select 2 union all select 3 union all
    select 4 union all select 5 union all select 6 union all
    select 7 union all select 8 union all select 9 union all
    select 0) N4
where N1.N * 1000 + N2.N * 100 + N3.N * 10 + N4.N in (1,2,3)
    and not exists (
        select * from customer c where c.customerid = v.number + v2.number*1000)

根据需要展开子查询以覆盖您的完整数字范围。

如果你可以创建表格(或有一个方便),创建一个“数字”表而不是数字0到9(10条记录),并继续加入自己,即

create table Numbers (N int)
insert into Numbers
select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9 union all
select 0

select N1.N * 1000 + N2.N * 100 + N3.N * 10 + N4.N as NonExistentCustomerID
from numbers N1
cross join numbers N2
cross join numbers N3
cross join numbers N4
where N1.N * 1000 + N2.N * 100 + N3.N * 10 + N4.N in (1,2,3)
    and not exists (
        select * from customer c where c.customerid = v.number + v2.number*1000)

numbers表对各种查询始终有用。

作为SQL Server的参考,假设数字在0-2047范围内,您可以使用

select v.number
from master..spt_values v
left join customer c on c.customerid = v.number
where v.type='P' and v.number in (1,2,3)
  and v.customerid is null

如果您需要更大的范围,请继续加入master..spt_values以获得更大的范围

select v.number + v2.number*1000 as NonExistentCustomerID
from master..spt_values v
inner join master..spt_values v2 on v2.type='P'
where v.type='P' and v.number + v2.number*1000 in (1,2,3)
  and v.number between 0 and 999
  and not exists (
    select * from customer c where c.customerid = v.number + v2.number*1000)
order by 1

答案 4 :(得分:1)

select customerId
  from customer
EXCEPT
select customerId
  from customer
 where customerId in (
          1, 2, 3
       )

答案 5 :(得分:1)

一种简单的方法是使用一个计数表,假设它的所有数字都是带有列号的数字(这段代码可能不是最好的,但应该清楚意图是什么):

select number
from numbers
where number in (1, 2, 3)
and number NOT IN (select customerId from customer)

另一种可能性是将您要查找的ID写入实际的表或表变量。