Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回按键排序的行加上缺少键的空行的SQL查询_Sql - Fatal编程技术网

返回按键排序的行加上缺少键的空行的SQL查询

返回按键排序的行加上缺少键的空行的SQL查询,sql,Sql,我有一个表,本质上是这样的结构: key value ------ ------ 2 val1 3 val2 5 val3 这些键是从1到目前的100万的连续整数,每天增加几千。删除记录时,键中会出现间隙 我正在寻找返回以下内容的SQL查询: key value ------ ------ 1 2 val1 3 val2 4 5

我有一个表,本质上是这样的结构:

key value ------ ------ 2 val1 3 val2 5 val3 这些键是从1到目前的100万的连续整数,每天增加几千。删除记录时,键中会出现间隙

我正在寻找返回以下内容的SQL查询:

key value ------ ------ 1 2 val1 3 val2 4 5 val3
我可以通过连接到第二个具有完整键列表的表来了解如何做到这一点。但是,我更喜欢使用标准SQL的解决方案,它不需要存储过程或第二个键表,而且无论键的上限值是多少,它都可以工作

SQL查询没有循环机制。过程语言有循环,但查询本身只能循环在表或派生表中找到的数据

我动态生成数字列表的方法是在数字0到9的小表上进行交叉连接:

CREATE TABLE n (d NUMERIC);
INSERT INTO n VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
然后生成00..99:

SELECT n1.d + n2.d*10 AS d
FROM n AS n1 CROSS JOIN n AS n10;
如果您只需要00..57:

SELECT n1.d + n2.d*10 AS d
FROM n AS n1 CROSS JOIN n AS n2
WHERE n1.d + n2.d*10 <= 57;
每次表的大小超过一个数量级时,确实需要添加另一个交叉联接。例如,当其增长超过100万时,为n6添加一个连接

请注意,我们现在可以在外部查询的WHERE子句中使用列别名


诚然,仅在SQL中执行此操作可能是一个非常昂贵的查询。您可能会发现,通过编写一些应用程序代码来填补空白既简单又快速。

在MySQL中,您可以通过使用正偏移量和负偏移量对自身执行左连接来找到空白的边缘

例如:


这并没有给出您想要的确切信息,但提供了足够的信息来确定缺少的行是什么。

另一种方法是创建一个百万个数字的结果集,并将其用作联接的基础。那可能对你有用。偷自

WITH range (num) AS (
SELECT 1 -- use your own lowerbound
UNION ALL
SELECT 1 + num FROM range
WHERE num < 10 -- use your own upper bound
)
SELECT r.num, y.* FROM range r left join yourtable y
on r.num = y.id
像这样屈服的

WITH 
upper_limit AS
(
    select 1000000 limit from dual
),
fake_table AS
(
    select  level key
    from    dual
    connect by level <= (select limit from upper_limit)
)
select key, value
from table, fake_table
where fake_table.key = table.key(+)

我不在工作,所以我不能测试这个。您的里程可能会有所不同。我在工作中使用Oracle。

很抱歉,我认为你指的是SQL查询,而不是SQL查询。它的发音是sequel,而不是ell…:-@本:如果你想学究气的话,习惯上是正确的,但在这种情况下,你不是。阅读SQL上的Wikipedia条目。这只适用于num<100的情况。SQL Server有100个递归调用的限制。OP说他想要一个标准的SQL解决方案,但是这个解决方案使用的Microsoft/Sybase功能不是标准的SQL。如果是标准的,我可能会使用游标来生成范围。在这个版本中有很多Oracle特定的语法,包括双连接方式,+但是OP说他想要一个标准的SQL解决方案。因此,您的里程数可能会有所不同。With不是特定于oracle的。它适用于其他数据库。例如sql server。
WITH range (num) AS (
SELECT 1 -- use your own lowerbound
UNION ALL
SELECT 1 + num FROM range
WHERE num < 10 -- use your own upper bound
)
SELECT r.num, y.* FROM range r left join yourtable y
on r.num = y.id
select  level
from    dual
connect by level <= 1000000
WITH 
upper_limit AS
(
    select 1000000 limit from dual
),
fake_table AS
(
    select  level key
    from    dual
    connect by level <= (select limit from upper_limit)
)
select key, value
from table, fake_table
where fake_table.key = table.key(+)