2

我有一个带有 int 值列的表,它的值在 0 到 43 之间(都包括在内)。

我想要一个返回不在表中的范围 [0,44) 的最小值的查询。

例如:
如果表包含:3,5,14。如果表包含:0,1,14,则查询应返回 0。
如果表包含:0,3,14,则查询应返回 2。
查询应返回1

如果表包含所有值,则查询应返回空。

我怎样才能做到这一点?

4

4 回答 4

5

由于您想要的值是0或大于表中存在的值,因此您可以这样做;

SELECT MIN(value)
FROM (SELECT 0 value UNION SELECT value+1 FROM MyTable) a
WHERE value < 44 AND value NOT IN (SELECT value FROM MyTable)

一个用于测试的 SQLfiddle

于 2013-08-09T06:14:37.097 回答
1

一种方法是创建另一个包含整数的表,[0,43]然后左连接并查找 NULL,NULL 会告诉您缺少哪些值。

假设你有:

create table numbers (n int not null);

此表包含从 0 到 43(含)的整数。如果您的表是t并且有一个n包含感兴趣数字的列,那么:

select n.n
from numbers n left join t on n.n = t.n
where t.n is null
order by n.n
limit 1

应该给你你想要的结果。

当您使用序列时,这是一种相当常见的 SQL 技术。最常见的用途可能是日历表。

于 2013-08-09T05:56:56.087 回答
0

有点 hacky 和 ​​MySQL 特定的:

SELECT NULLIF(MAX(IF(val=@min, @min:=(val+1), @min)), @max) as min_empty
FROM (
  SELECT DISTINCT val
  FROM table1
  -- WHERE val BETWEEN 0 AND 43
  ORDER BY val) as vals, (SELECT @min:=0, @max:=44) as init;
于 2013-08-09T06:42:15.467 回答
0

一种方法是生成一组具有整数值的 44 行,然后针对表中的不同值集执行反连接,并获取最小值。

SELECT MIN(r.val) AS min_val
  FROM ( SELECT 0 AS val UNION ALL
         SELECT 1 UNION ALL
         SELECT 2 UNION ALL
         SELECT 3 UNION ALL
         SELECT 4 UNION ALL
         SELECT 5 UNION ALL
         -- ... 
         SELECT 44 
       ) r
  LEFT
  JOIN ( SELECT t.int_valued_col
           FROM mytable t
          WHERE t.int_valued_col >= 0
            AND t.int_valued_col <= 43
          GROUP BY t.int_valued_col
       ) v
    ON v.int_valued_col = r.col
 WHERE v.int_valued_col IS NULL
于 2013-08-09T06:01:45.947 回答