组连续数字的范围

时间:2015-11-26 05:26:48

标签: sqlite

考虑表:

Point    | Seq_number|timestamp
------------------------------
50000    | 3002      |6000
-----------------------------
50001    | 3003      |7000
------------------------------
50002    | 3004      |1000
------------------------------
50003    | 3005      |2000
------------------------------
50004    | 1         |3000
------------------------------
50005    | 2         |4000
------------------------------
50006    | 3         |4000
------------------------------
50007    | 4         |4000
------------------------------
50008    | 5         |5000
------------------------------
50009    | 6         |10000
------------------------------
and so on records
------------------------------

我想要所有记录 时间戳范围= 1000到7000
点范围= 50000至50030,不包括50003
按序列号按升序排序上表。

我已将SQL查询编写为

select *
from ( select *
       from NV_DB_LOGLKUP
       where point IS NOT 50003
         and point between 50000 and 53000 ) 
where timestamp between 1000 and 7000
order by seq_number asc ;

以上查询正在运行。上述查询的结果将是: enter image description here

对于上面的表共享,我想编写通用SQL查询,它将输出为 enter image description here

输出表中的条目是在seq_num和point中的“之一或两者”与输入表中的前一个记录不连续时生成的。 注意:50004到50008,seq_number是顺序的。相同的是50000到50002.但是对于50030记录,点不是它的前记录点(50002)。同样对于50031记录,seq_num不是其上一个记录seq_number(3005)的顺序。

我可以更改上面写的SQL查询并使其更紧凑。

谢谢

1 个答案:

答案 0 :(得分:0)

如果没有上一行,则行是范围中的第一行:

WITH interesting_data AS (
  SELECT point,
         seq_number
  FROM NV_DB_LOGLKUP
  WHERE point BETWEEN 50000 AND 53000
    AND point != 50003
    AND timestamp BETWEEN 1000 AND 7000
)
SELECT point AS first_point
FROM interesting_data
WHERE NOT EXISTS (SELECT 1
                  FROM interesting_data AS previous
                  WHERE previous.point = interesting_data.point - 1);

相应的最后一行是第一个点或后面没有下一个点的第一行:

WITH interesting_data AS (
  SELECT point,
         seq_number
  FROM NV_DB_LOGLKUP
  WHERE point BETWEEN 50000 AND 53000
    AND point != 50003
    AND timestamp BETWEEN 1000 AND 7000
), first_points AS (
  SELECT point AS first_point,
         seq_number
  FROM interesting_data
  WHERE NOT EXISTS (SELECT 1
                    FROM interesting_data AS previous
                    WHERE previous.point = interesting_data.point - 1)
)
SELECT first_point,
       (SELECT MIN(point)
        FROM interesting_data
        WHERE point >= first_points.first_point
          AND NOT EXISTS (SELECT 1
                          FROM interesting_data AS next
                          WHERE next.point = interesting_data.point + 1)
       ) AS last_point
FROM first_points
ORDER BY seq_number;

如果您有较旧的SQLite版本不支持WITH,请更新它,或将查询写为视图,或直接将它们作为子查询插入。