2013-08-22 22 views
0

为什么下一个小提琴不给我102? 我正在寻找两列中都不存在的最小数字。Oracle SQL中两个不同列中最小的不存在编号

注意:一列是数字,另一列是varchar。

SELECT NVL(MIN(a1.id_int)+1, 111) 
    FROM bPEOPLE a1 
WHERE NOT EXISTS (SELECT 1 
        FROM PEOPLE a2 
        WHERE a2.id_int=a1.id_int+1 
        ) 
    AND NOT EXISTS (SELECT 1 
         FROM PEOPLE a3 
        WHERE TO_NUMBER(a3.id_str)=a1.id_int+1 
        ) 
    AND a1.id_int + 1 > 100 
    AND a1.id_int + 1 < 110; 

Sql Fiddle

回答

2

因为你的表达:

NVL(MIN(a1.id_int)+1, 111) 

只引用INT列,其中的下一个值是108

您需要将两列合并成一列,然后拿到MIN:

SELECT NVL(MIN(a.id_int)+1, 111) as next_id 
FROM ( SELECT id_int 
      FROM PEOPLE 
      UNION ALL 
      SELECT TO_NUMBER(id_str) AS id_int 
      FROM PEOPLE 
     ) a 
WHERE NOT EXISTS 
     ( SELECT 1 
      FROM PEOPLE b 
      WHERE a.id_int + 1 IN (b.id_int, TO_NUMBER(b.id_str)) 
     ); 

Example on SQL Fiddle

1

,因为你从id_int列开始,然后添加1你没有得到102。您必须在id_int列中有101个以便有机会获得102.

换句话说,您的错误是,您以MIN(a1.id_int)开头并忽略MIN(TO_NUMBER(a3.id_str))

这可能是你想要

SELECT NVL(MIN(n)+1, 111) FROM 
(
    SELECT id_int as n FROM PEOPLE 
    UNION 
    SELECT TO_NUMBER(id_str) as n FROM PEOPLE 
) p 
WHERE 
    NOT EXISTS 
    (
    SELECT 
     1 
    FROM 
     PEOPLE a2 
    WHERE 
     a2.id_int=n+1 
) 
    AND 
    NOT EXISTS 
    (
     SELECT 
     1 
     FROM 
     PEOPLE a3 
     WHERE 
     TO_NUMBER(a3.id_str)=n+1 
    ) 
AND n + 1 > 100 
AND n + 1 < 110; 
0

我不知道为什么它给你错误的结果是什么,但我想你可以创建两列的联合,发现没有按”最小吨有一家挨着一家,并添加一个到它

尝试

SELECT MIN(t1.id)+1 
FROM (
    SELECT CAST(id_str AS INT) id 
    FROM people 
    UNION 
    SELECT id_int 
    FROM people 
) t1 
LEFT JOIN (
    SELECT CAST(id_str AS INT) id 
    FROM people 
    UNION 
    SELECT id_int 
    FROM people 
) t2 ON t2.id = t1.id+1 
WHERE t2.id IS NULL 

demo

0

not exists条款AR é说“排除其他行有比当前行大1的行”。唯一的行是真正的行是最后一行,而你的问题意味着你想要第一行。

要解决此问题,您只需将not exists子句中的+1移动到谓词中的其他列。

另外,在小提琴中,你增加了可以容纳105的整数值。如果你想递增101,那么你需要在你的函数中选择id_str列。

SELECT 
    NVL(MIN(a1.id_str)+1, 111) 
FROM 
    PEOPLE a1 
WHERE 
    NOT EXISTS 
    (
    SELECT 
     1 
    FROM 
     PEOPLE a2 
    WHERE 
     a2.id_int+1=a1.id_int 
) 
    AND 
    NOT EXISTS 
    (
     SELECT 
     1 
     FROM 
     PEOPLE a3 
     WHERE 
     TO_NUMBER(a3.id_str)+1=a1.id_int 
    ) 
AND a1.id_int + 1 > 100 
AND a1.id_int + 1 < 110; 

最后,在数据集中提供你实际上并不需要应用min功能,(101,105)行被选中的唯一一个。但是,您仍然需要用真实数据集中的最小值。

相关问题