compare user supplied list against table, with nulls for non-matching rows

时间:2018-03-09 19:16:14

标签: sql db2

Given a list of user-supplied numbers, which I'll refer to as myList, I want to find out which ones have a match against table MasterList, and which ones are null (no match)

so, given db contents

MasterList
----------

ID    Number
1     3333333
2     4444444
3     5555555

If myList is ['1111111','2222222','3333333','4444444']

I want the following output:

1111111, null
2222222, null
3333333, 1
4444444, 2   

Ideas I've tried:

This, of course, yields only the ones that match.

select Number, ID
from MasterList
where Number in('1111111','2222222','3333333','4444444')

My next idea is no more helpful:

select temp.Number, master.Number
from MasterList master 
left join MasterList temp 
    on master.id=temp.id 
       and temp.Number in('1111111','2222222','3333333','4444444')

If the list were itself a table temp, it would be trivial to get the desired output:

select temp.number, master.id 
from temp    -- (ie, the list, where temp.number is the given list)
left join master on master.number=temp.number
-- optional where
where temp.number in('1111111','2222222','3333333','4444444')

This idea never materialized:

select temp.number, master.id
from (select '1111111','2222222','3333333','4444444') temp
left join master on master.number on.... 

Can this be done without a temporary table?

If not, how do you make a temporary table in DB2? (IBM documentation is helpful if you already know how to do it...)

2 个答案:

答案 0 :(得分:4)

你想要一个外连接,这里是一个左外连接(我们想要左边的所有行和右边的任何与连接条件匹配的行),正如你在问题中正确地说的那样。在这里,我使用公用表表达式(CTE)来基本上创建临时表。

WITH inlist (num) as ( VALUES 
  (111111),
  (222222),
  (333333),
  (444444) )
SELECT num, id 
FROM inlist LEFT OUTER JOIN masterlist
    ON masterlist.number = inlist.num
ORDER BY num;

产量:

NUM         ID         
----------- -----------  
     111111           -  
     222222           -  
     333333           1  
     444444           2  

  4 record(s) selected.

答案 1 :(得分:1)

我不熟悉DB2(至少在15年内没有为此编写SQL,当时也不多),所以我不知道你有多少&#39 ;我需要编辑它以使其工作,但我认为这将做你想要的(编辑SQL使用VALUES子句)

SELECT 
    my.Number1,
    CASE WHEN ml.Number1 IS NULL
    THEN NULL
    ELSE ROW_NUMBER() OVER (ORDER BY my.Number1) END AS Indicator
FROM 
    (VALUES ('1111111'),('2222222'),('3333333'),('4444444')) 
    AS my(Number1)
LEFT JOIN
    MasterList AS ml
ON
    my.Number1 = ml.Number1;