2015-04-22 133 views
1

我很努力想出一种方法来解决这个问题。我想从一个特定的价值开始,每增加一个新的线就不断增加1。SQL循环增加数字

例如,如果我有这样的表。

90  
93  
110 
87  
130 
Etc.. 

我要选择的号码87,然后继续从那里增加了,但也看到如果增加的数量是存在的,跳过它。

我只是努力将正确的逻辑放在我的脑海。我知道我需要一段时间的循环来继续阅读桌面,但我想不出正确的方式去做。只是寻求一些建议来推动我朝着正确的方向发展。

编辑:我使用T-SQL的MSFT SQL Server 2012的

这里的输出应该是什么样子

90  
93  
110 
87  
130 
88  
89  
91  
92  
94 

这将跳过增加90和93的例子,因为他们已经存在于表格中。

我希望这对你们有意义。

+1

请编辑您的问题,并显示你正在试图获得满意的结果。还要用您实际使用的数据库标记问题。 –

+1

作为一般的SQL观察,您不应该在程序上考虑解决方案。虽然许多方言支持迭代,但在大多数情况下,一套(或可能是序列)导向的方法将更加稳健地为您提供正确的结果。为了更好地回答您的问题,请提供输入和输出表的具体示例。 – Pekka

+0

所以,重点是让所有的数字在一个范围内失踪? – UnhandledExcepSean

回答

0

我做的这一切在一个递归CTE和我做,所以你可以通过使用秩序,保障您的结果以正确的顺序返回。

对于递归,您可以选择并开始和结束数字或@desiredNumberOfNewValues(请记住,它不考虑重复)。如果您有任何问题或需要任何其他信息,请告知我。

DECLARE @yourTable TABLE (nums INT); 
INSERT INTO @yourTable 
    VALUES (90),(93),(110),(87),(130); 


DECLARE @Specific_Number INT = 87; 
DECLARE @Last_Number INT = 94; 
DECLARE @DesiredNumberOfNewValues INT = 7; 

WITH CTE_Numbers 
AS 
(
    SELECT 1 AS order_id,nums, 1 AS cnt 
    FROM @yourTable 

    UNION ALL 

    SELECT 2, 
      CASE 
       WHEN @Specific_Number + cnt NOT IN (SELECT * FROM @yourTable) --if it's not already in the table, return it 
        THEN @Specific_Number + cnt 
       ELSE NULL -- if it is in the table, return NULL 
      END, 
      cnt + 1 
    FROM CTE_Numbers 
    WHERE nums = @Specific_Number 
      --OR (cnt > 1 AND @Specific_Number + cnt < @Last_Number) --beginning and end(option 1) 
      OR (cnt > 1 AND cnt <= @DesiredNumberOfNewValues) --number of new values(option 2) 
) 

SELECT order_id,nums 
FROM CTE_Numbers 
WHERE nums IS NOT NULL 
ORDER BY order_id,nums 

结果:

order_id nums 
----------- ----------- 
1   87 
1   90 
1   93 
1   110 
1   130 
2   88 
2   89 
2   91 
2   92 
2   94 
0
WITH Numbers_CTE (Number) 
AS 
(
    SELECT 1 AS Number 
    UNION ALL 
    SELECT Number+1 FROM Numbers_CTE 
) 
SELECT top 10 * 
FROM Numbers_CTE n 
LEFT JOIN <TABLE> t ON t.ID=n.Number 
WHERE t.ID IS NULL 
AND n.Number BETWEEN 5 AND 100 
0

有可以使用名为master..spt_values数字的系统表。

DECLARE样品台

DECLARE @tbl TABLE(Id INT) 

INSERT语句

INSERT INTO @tbl VALUES (90) 
         ,(93)  
         ,(110) 
         ,(87)  
         ,(130) 

您可以轻松地做出UNION去除内CTE

重复珍惜你在你的桌子和 ORDER
DECLARE @number INT = 87 

;WITH C AS(
    SELECT Id, Row_Id, ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Id) AS Rn FROM (
     SELECT 1 AS Row_Id, Id FROM @tbl 
     UNION 
     SELECT 2 AS Row_Id, number 
     FROM master..spt_values 
     WHERE [type] = 'P' 
     AND number >= @number 
    ) t 
) 
SELECT Id FROM C 
WHERE Rn = 1 
ORDER BY Row_Id, Id 

输出

Id 
---- 
87 
90 
93 
110 
130 
88 
89 
91 
92 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
111 
112 
113 
114 
. 
. 
. 

SQLFiddle

+0

除非你的联盟不工作,因为你的row_id不同,所以你需要重复OP和OP所不需要的90和93。 – Stephan

+0

感谢您指出。修复了这个问题。 – sqluser