2013-08-22 23 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)行被選中的唯一一個。但是,您仍然需要用真實數據集中的最小值。

相關問題