将列与一组数字进行比较

时间:2017-11-03 19:39:15

标签: sql oracle plsql

我必须将数据库中的列与一组数字进行比较。基本上,我想输出集合中的所有数字,但不输出表格。

我试过这个,但我仍然得到了集合中的列,但不在表格中。

这是我到目前为止所尝试的,

DECLARE
  CURSOR c_applnbr IS
    SELECT * FROM appl a
    WHERE a.applnbr IN 
    (7701, 7702, 7703, 7704, 7705, 7706, 7707, 7708, 7709, 7710, 7711,
    7712, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 
    7723, 7724, 7725, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 
    7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7743, 7744, 7745,
    7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756,
    7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767,
    7768, 7769, 7770, 7771, 7772, 7773, 7774, 7775, 7776, 7777, 7778, 
    7779, 7781, 7782, 7783, 7784, 7786, 7787, 7788, 7789, 7791, 7792,
    7798, 7799, 7801, 7802, 7803, 7804, 7805, 7818, 7819, 7833); -- There is no 7833 in the table
  CURSOR c_applnbr_total IS SELECT * FROM appl;

  TYPE t_applnbr IS TABLE OF appl.applnbr%TYPE;

  applnbrs t_applnbr := t_applnbr();
  applnbrs_total t_applnbr := t_applnbr();
  commonNumbers t_applnbr := t_applnbr();

  counter integer := 0;
  counter2 integer := 0;


BEGIN
  -- Fill applnbrs
  FOR n IN c_applnbr LOOP
    counter := counter + 1;
    applnbrs.EXTEND;
    applnbrs(counter) := n.applnbr;
  END LOOP;
  -- Fill applnbrs_total
  FOR n IN c_applnbr_total LOOP
    counter2 := counter2 + 1;
    applnbrs_total.EXTEND;
    applnbrs_total(counter2) := n.applnbr;
  END LOOP;
  -- Getting the numbers in the set, and not in the table.
  commonNumbers := applnbrs MULTISET EXCEPT DISTINCT applnbrs_total;
  -- Checking counts
  dbms_output.put_line('applnbrs count: ' || applnbrs.COUNT); -- Holds 97
  dbms_output.put_line('applnbrs_total count: ' || applnbrs_TOTAL.COUNT); -- Holds 1979
  dbms_output.put_line('commonNumbers.count: ' || commonNumbers.COUNT); -- Holds 0

  FOR n IN 1..commonNumbers.COUNT LOOP -- Doesn't go in loop
    dbms_output.put_line(n || ': ' || commonNumbers(n));        
  END LOOP;

END;

我暂时没有做过Pl / SQL,所以也许我没有正确使用嵌套表。

表格中没有7833的条目。因此,所需的输出应该吐出7833,但commonNumbers.COUNT = 0。基本上所有东西都匹配。

2 个答案:

答案 0 :(得分:1)

解决方案是使用生成所需值的查询。类似的东西:

select 7701 as applnbr from dual union all
select 7702 from dual union all
select 7703 from dual union all
select 7704 from dual union all
select 7705 from dual

...等等。因为这个很长,并且你的数字的很大一部分是连续的,你也可以用递归查询压缩这一点:

select applnbr 
from   (select 7700 + level as applnbr from dual connect by level < 134)
where  applnbr not in (7726, 7780, 7785, 7790, 7800)
and    applnbr not between 7793 and 7797
and    applnbr not between 7806 and 7817
and    applnbr not between 7820 and 7832

这将产生7701和7833之间的所有数字,然后通过where子句删除其中一些数字以获得实际集合。

最后,您可以使用外部联接来获得所需的结果:

with needed as (
     select applnbr 
     from   (select 7700 + level as applnbr from dual connect by level < 134)
     where  applnbr not in (7726, 7780, 7785, 7790, 7800)
     and    applnbr not between 7793 and 7797
     and    applnbr not between 7806 and 7817
     and    applnbr not between 7820 and 7832
)
select    needed.applnbr 
from      needed
left join appl
       on appl.applnbr = needed.applnbr
where     appl.applnbr is null

答案 1 :(得分:1)

您可以在简单选择中使用XMLTABLE函数和NOT EXISTS。不需要PL / SQL。

SELECT * FROM 
(
SELECT
    to_number(column_value) AS appl
FROM
    XMLTABLE ( '7701, 7702, 7703, 7704, 7705, 7706, 7707, 7708, 7709, 7710, 7711,
    7712, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 
    7723, 7724, 7725, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 
    7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7743, 7744, 7745,
    7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756,
    7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767,
    7768, 7769, 7770, 7771, 7772, 7773, 7774, 7775, 7776, 7777, 7778, 
    7779, 7781, 7782, 7783, 7784, 7786, 7787, 7788, 7789, 7791, 7792,
    7798, 7799, 7801, 7802, 7803, 7804, 7805, 7818, 7819, 7833'
) ) t  WHERE
NOT EXISTS (
    SELECT
        1
    FROM
        applnbr a
    WHERE
        a.appl = t.appl
);

注意XMLTABLE仅适用于Numbers。