在SQL Server中,如果我有一个int变量,如何编写一个通过int变量的值返回值1的查询?
所以给出:
declare @cnt int
set @cnt = 5
什么查询会返回1 - 5?这可能吗?
答案 0 :(得分:5)
已经给出的其他人的替代答案,可能不那么实用,但在某些情况下可能更快。
如果你有一个已知的@cnt值的上限你会遇到(比如1000)你可以创建一个简单的单列表,其中包含前1000个整数,比如
val --- 1 2 3 4 ...
然后,只要你想要一组整数,就可以使用
获得它select val from integerTable where val <= @cnt
答案 1 :(得分:4)
您可以在SQL中执行 WHILE 循环,如下所示:
DECLARE @Cnt int,
@Val int;
SET @Cnt = 5;
SET @Val = 0;
DECLARE @MyValues TABLE
(
val int
);
WHILE @Val < @Cnt
BEGIN
SET @Val = @Val + 1;
INSERT @MyValues(val)
SELECT @Val;
END;
SELECT Val FROM @MyValues;
答案 2 :(得分:2)
您可以使用recursive CTE在一个查询中执行此操作,但如果您的@cnt以非常高的值启动,则需要注意MAXRECURSION查询提示。
DECLARE @cnt int;
SET @cnt = 5;
WITH Numbers AS (
SELECT @cnt [Value]
UNION ALL
SELECT [Value] - 1
FROM Numbers
WHERE [Value] > 1
)
SELECT * FROM Numbers
ORDER BY [Value]
尽管如此,使用简单的WHILE循环进行操作会更简单,更容易阅读。
答案 3 :(得分:1)
您只需在查询结尾处使用SELECT语句即可轻松实现“输出”值...
SELECT ... FROM ... WHERE ... Bla Bla, yadah, yadah;
SELECT (1 - @cnt);
您将获得所需的输出。
答案 4 :(得分:1)
这是一个执行此操作的功能:
CREATE FUNCTION [dbo].[Sequence] (@start int, @end int, @step int)
RETURNS @result table (num int) AS
BEGIN
declare @num int
set @num = @start
while @num <= @end
begin
insert into @result (num) values (@num)
set @num = @num + @step
end
return
END
使用此功能,您可以选择以下序列:
select * from dbo.Sequence(1,5,1)
返回1,2,3,4,5。
select * from dbo.Sequence(2,6,2)
将返回2,4,6。等等:)
答案 5 :(得分:1)
如果上下文中@cnt的最大值相对较低,则可以填充临时或持久的整数表,并从中选择或加入。
CREATE TABLE LotsOfNumbers(Number int not null)
INSERT INTO LotsOfNumbers VALUES(1)
INSERT INTO LotsOfNumbers VALUES(2)
INSERT INTO LotsOfNumbers VALUES(3)
...
INSERT INTO LotsOfNumbers VALUES(99)
INSERT INTO LotsOfNumbers VALUES(100)
DECLARE @cnt INT
SET @cnt = 30
SELECT *
FROM LotsOfNumbers
WHERE Number <= @cnt
ORDER BY Number
当然,时间/空间性能取决于您的情况,因此我会观察SQL事件探查器以了解每种方法对数据库的命中。
答案 6 :(得分:0)
declare @cnt int
set @cnt = 0
while @cnt < 5
begin
set @cnt = @cnt + 1
print 'The counter is ' + cast(@counter as char)
end
答案 7 :(得分:0)
不知道您是否只想要一个结果集(根据José Basilio's answer)或者对多个结果感到满意
DECLARE @ctr INT
DECLARE @start INT
SET @ctr = 5
SET @start = 1
WHILE @start <= @ctr
BEGIN
SELECT @start
SET @start = @start + 1
END
答案 8 :(得分:0)
使用数字生成单列表很容易。
Create Table Numbers(Number INT);
INSERT INTO Numbers(Number) values(0);
INSERT INTO Numbers(Number) values(1);
INSERT INTO Numbers(Number) values(2);
.
.
INSERT INTO Numbers(Number) values(9);
-- To generate a list of 100000
SELECT * INTO TEST
FROM
(SELECT N1.Number * 1000 + N2.Number * 100 + N3.Number * 10 + N4.Number * 1 as Num
FROM Numbers N1
CROSS JOIN Numbers N2
CROSS JOIN Numbers N3
CROSS JOIN Numbers N4) AS N
ORDER BY Num;
--Then, You can use the above table for getting the numbers
SELECT * from TEST WHERE Num <= 5;
答案 9 :(得分:0)
我不得不在几年前处理这个问题,所以如果你的数据库有一个比你需要计算更多记录的表,我想出了最快/最简单的方法。
首先,尽管建议您不需要“创建”记录表...您只需要“ANY”表已经有记录。只要表中记录的记录多于您需要的记录,那么您就是好的。
SELECT top (5) ROW_NUMBER() OVER(Order by [Primary_Key] desc) AS Integer
FROM SOME_TABLE --that has more than 5 rows.
这也是优雅的(数学)方式。数据库中已有大表的地方。
使用Split递归,这允许您生成一个最多包含2 ^ n-1个整数的表,其中n是递归限制。此外,这是完全参数化的,因此可以轻松地将其放入函数
DECLARE @n int, @cnt int;
set @cnt = 5;
SET @n = LOG(@cnt)/LOG(2) +1; --use change of base to find LOG base 2
WITH Num AS (
SELECT @n [Value]
UNION ALL
SELECT [Value] - 1
FROM Num
WHERE [Value] > 1
UNION ALL
SELECT [Value] - 1
FROM Num
WHERE [Value] > 1
)
SELECT * from (
SELECT ROW_NUMBER() OVER(Order by Value asc) AS [Integer]
FROM Num
)i
where [Integer] <= @cnt
这样做的一个缺点是它在递归期间可以生成最多两倍的记录,因此它有可能比内联递归产生更多的开销。但由于这一点,完全避免了递归限制。 (你不应该需要列出前2 ^ 100-1个整数。)(我也只是预测你没有那么多硬盘空间的计算机。)
这个缺点是我创建下一个功能的原因。它使用与分割递归相同的倍增技术但在while循环内。并且它最后一次运行它只会使必要的记录不加倍。此功能还允许您指定范围并返回该范围内的所有数字,并使用这些数字的0索引。我曾经认为零基本列是计算中无用的工件,但是将范围及其索引放在一行中非常有帮助。
create function [dbo].[fn_Integers]
(
@Min_Integer int = 1
,@Max_Integer int
)
RETURNS @retTable TABLE
([BASE] int identity(0,1)
,[INTEGER] int)
AS
BEGIN
Declare @RANGE int
SET @RANGE = @Max_Integer-@Min_Integer
insert into @retTable
select NULL --initial value for recursion
While ((SELECT MAX([BASE]) FROM @retTable r) < @RANGE )
BEGIN
INSERT into @retTable
select [INTEGER] from @retTable r
where [BASE] < (SELECT @RANGE - MAX([BASE]) FROM @retTable r)
END
Update @retTable set
[INTEGER] = [BASE] + @Min_Integer
RETURN
END
GO
它每秒可以做大约50000个整数(在我的工作站上) 和输出看起来像
SELECT * FROM [fn_Integers](18,50000)
BASE INTEGER
-----------------
0 18
1 19
2 20
...
49982 50000