意图:检测数字序列是否包含间隙。无需识别缺失的元素,只需标记(true / false)序列(如果它包含间隙)。
CREATE TABLE foo(x INTEGER);
INSERT INTO foo(x) VALUES (1), (2), (4);
下面是我(显然正常运行的)查询以检测间隙:
WITH cte AS
(SELECT DISTINCT x FROM foo)
SELECT
( (SELECT COUNT(*) FROM cte a
CROSS JOIN cte b
WHERE b.x=a.x-1)
=(SELECT COUNT(*)-1 FROM cte))
OR (NOT EXISTS (SELECT 1 FROM cte))
表格为空的边缘情况需要OR
。查询的逻辑基于以下观察:在连续序列中,链接数等于元素数减1。
更具惯用性或高性能(我应该担心特别长序列中的CROSS JOIN?)
答案 0 :(得分:2)
试试这个:
SELECT
CASE WHEN ((MAX(x)-MIN(x)+1 = COUNT(DISTINCT X)) OR
(COUNT(DISTINCT X) = 0) )
THEN 'TRUE'
ELSE 'FALSE'
END
FROM foo
答案 1 :(得分:2)
以下内容应检测是否存在缺口:
select (case when max(x) - min(x) + 1 = count(distinct x)
then 'No Gaps'
else 'Some Gaps'
end)
from foo;
如果没有间隙或重复,则x的不同值的数量是最大值减去min加1。
答案 2 :(得分:1)
另一种方法......
如果从最大值中减去最小值,并加1,则应该等于计数。
如果count =(max-min)+1,那么“没有差距!”
如果你能在SQL中表达它,它应该非常有效。
答案 3 :(得分:1)
SELECT 'Has ' || count(*) - 1 || ' gaps.' AS gaps
FROM foo f1
LEFT JOIN foo f2 ON f2.id = f1.id + 1
WHERE f2.id IS NULL;
诀窍是计算行,缺少下一行 - 如果没有间隙,则只发生 last 行。
如果没有行,则会获得'Has -1 gaps.'
如果没有差距,则会获得'Has 0 gaps.'
否则,'Has n gaps.'
.. n
是确切的间隙数,无论多大
对于重复项,可以增加计数,但0
和-1
不受欺骗的影响。