How to generate Fibonacci Series [closed] - sql

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
How to Generate Fibonacci series in sql !
I need to generate Fibonacci series 0 1 1 2 3 5 8 13 21 ... N
I did this easily using C-code I need to do this using Sql !

Try This Simple Query:
1) For Result In Row-by-Row (Single Column, Multiple Rows)
WITH Fibonacci (PrevN, N) AS
(
SELECT 0, 1
UNION ALL
SELECT N, PrevN + N
FROM Fibonacci
WHERE N < 1000000000
)
SELECT PrevN as Fibo
FROM Fibonacci
OPTION (MAXRECURSION 0);
Output 1:
2) For Result in Only One Row (Comma sepreted, in Single Cell)
WITH Fibonacci (PrevN, N) AS
(
SELECT 0, 1
UNION ALL
SELECT N, PrevN + N
FROM Fibonacci
WHERE N < 1000000000
)
SELECT Substring(
(SELECT cast(', ' as varchar(max)) + cast(PrevN as varchar(max)
);
FROM Fibonacci
FOR XML PATH('')),3,10000000) AS list
Output 2:

Try this !
declare #a int
declare #b int
declare #c int
Declare #i int
set #a=0
set #b=1
set #i=0
set #c=0
Print 'Fibonacci Series'
print #a
print #b
while #i<10
Begin
set #c=#a+#b
print #c
set #i=#i+1
set #a=#b
set #b=#c
end
Outputs !
Fibonacci Series
0
1
1
2
3
5
8
13
21
34
55
89

Please try:
SELECT 0 AS fib_number UNION ALL
SELECT
FLOOR(POWER(( 1 + SQRT(5) ) / 2.0, number) / SQRT(5) + 0.5)
FROM master..spt_values
WHERE TYPE = 'p' AND number BETWEEN 1 AND 70

Try this :-
Declare #Fib int = 5
;with cte as
(
Select 0 as Previous,1 as Next ,0 as Level
union all
Select Next,Next + Previous,Level +1 from cte
where Level +1 <#Fib
)
Select Previous as FibonacciSeries from cte

This is for generating the first 10 numbers in the series.
DECLARE #NoOne INT, #NoTwo INT
DECLARE #FibonacciTable TABLE (Number INT NOT NULL)
--Insert first two numbers 0 and 1
INSERT #FibonacciTable (Number) SELECT 0 UNION ALL SELECT 1
SELECT #NoOne = 0, #NoTwo = 1
WHILE (SELECT COUNT(*) FROM #FibonacciTable) < 10
BEGIN
INSERT #FibonacciTable (Number) VALUES(#NoOne + #NoTwo)
SELECT #NoTwo = #NoOne + #NoTwo, #NoOne = #NoTwo - #NoOne
END
SELECT * FROM #FibonacciTable
GO

CREATE TABLE #Fibonacci (value BIGINT)
GO
INSERT INTO #Fibonacci(value) SELECT 0
INSERT INTO #Fibonacci(value) SELECT 1
SELECT * FROM #Fibonacci
GO
INSERT INTO #Fibonacci(value)
SELECT SUM(value) FROM ( SELECT TOP 2 * FROM #Fibonacci ORDER BY value DESC ) AS value
GO 10 -- Loop insert 10 value...
SELECT * FROM #Fibonacci
DROP TABLE #Fibonacci
Result Code

Related

Difference between two columns into separate rows for each value between the two

I'm having trouble explaining my problem but I have this table
ID START END
1 10 12
2 30 31
3 11 13
and want something like this:
ID NUMBER
1 10
1 11
1 12
2 30
2 31
3 11
3 12
3 13
I need the all unique whole numbers between the two columns transform into separate rows.
Here's how I want the transformation to look like
I haven't tried anything because I don't even know how to call such procedure so any help is appreciated
If you don't have a numbers table (highly recommended), you can use an ad-hoc tally table in concert with a CROSS APPLY
Example
Select A.ID
,B.Number
From YourTable A
Cross Apply ( Select Top ([End]-[Start]+1)
Number=[START]-1+Row_Number() Over (Order By (Select NULL))
From master..spt_values n1, master..spt_values n2
) B
Returns
ID Number
1 10
1 11
1 12
2 30
2 31
3 11
3 12
3 13
In SQL Server, you can use a recursive CTE:
with cte as (
select id, [start] as number, [end] as end_number
from t
union all
select id, number + 1
from cte
where number < end_number
)
select id, number
from cte;
Note: If the span can exceed 100, you need option (maxrecursion) for the query.
Recursive CTEs are usually a bit slower than a numbers table. However, I find them much faster than I would expect.
--create table NewTable
--(
--ID int,
--NUMBER int
--)
DECLARE #ID nvarchar(50)
declare #START int
declare #END int
DECLARE Cursor_Name CURSOR
FOR
select ID, [START], [End] from tblSequences
OPEN Cursor_Name
FETCH NEXT FROM Cursor_Name INTO #ID,#START,#END
WHILE ##FETCH_STATUS = 0
begin
WHILE #START<=#END
begin
insert into NewTable (ID, NUMBER) Values (#ID, #START)
set #START = #START+1
end
FETCH NEXT FROM Cursor_Name INTO #ID,#START,#END
end
CLOSE Cursor_Name
DEALLOCATE Cursor_Name
select * from NewTable

sum of factorial of the no [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Want to find sum of digits of factorial of a num?
But i need the sum of the result like 5! is 120
in this i want 1+2+0=3
This can be achieved with help of recursive CTE:
--here you decide what factorial to calculate
declare #i int = 5;
;with cte as(
select 1 n, 1 factorial
union all
select n + 1, factorial * (n + 1) from cte
where n < #i
)
select factorial,
--just to make sure we correctly sum all digits
(factorial%100000)/10000 +
(factorial%10000)/1000 +
(factorial%1000)/100 +
(factorial%100)/10 +
factorial%10 DigitsSum
from cte
where n = #i
You can use code like this:
declare #a int
set #a = 120
declare #temp varchar(20)
set #temp = cast(#a as varchar(20))
declare #Result int
set #Result = 0
declare #tempLength int
set #tempLength = DATALENGTH(#temp)
while #tempLength > 0
begin
set #Result = #Result + cast(SUBSTRING(#temp, #tempLength, 1) as int)
set #tempLength = #tempLength - 1
end
select #Result
Variable "a" is same your factorial result.
try substring() function and separate the digits and then add all togather.
You can Create a function from sum of factorial of the no To Find out the Factorial of a number.
Then use below query to find the Sum:
DECLARE #var1 int
select #var1 = dbo.Factorial(5)
;WITH i AS (
SELECT #var1 / 10 n, #var1 % 10 d
UNION ALL
SELECT n / 10, n % 10
FROM i
WHERE n > 0
)
SELECT SUM(d)
FROM i;

How to select only armstrong numbers from the list?

I want is to select Armstrong numbers from the list below list I have searched of solution of this question bu unable to find in SQL-Server:
Numbers
121
113
423
153
541
371
I am sure most of you know what's the Armstrong number and how to calculate though I am describing is for the simplicity : sum of the cubes of its digits is equal to the number itself i.e.
1*1*1 + 5*5*5 + 3*3*3 = 153
3*3*3 + 7*7*7 + 1*1*1 = 371
Please help me on this as I am also trying but seeking for quick solution. It will be very helpful to me. Thanks in advance.
Obviously static processing during each query is not correct approach but we can create function like this and
create function dbo.IsArmstrongNumber(#n int)
returns int as
begin
declare #retValue int = 0
declare #sum int = 0
declare #num int = #n
while #num > 0
begin
set #sum += (#num%10) * (#num%10) * (#num%10)
set #num = #num/10
end
IF #sum = #n
set #retValue = 1
return #retValue
end
Pre-processing and selecting in IN clause is better
select * from #Numbers where dbo.IsArmstrongNumber(n) = 1
select 153 x into #temp;
insert #temp values(371);
insert #temp values(541);
with cte as (select x, substring(cast(x as nvarchar(40)) ,1,1) as u, 1 as N FROM #temp
union all
select x, substring(cast(x as nvarchar(40)),n+1,1) as u , n+1 from cte where len(cast(x as nvarchar(40))) > n
)
select x from cte group by x having SUM(POWER(cast(u as int),3)) = x
drop table #temp;
here is the mark 2 - you can change the #ORDER to explore power of 4,5 etc
declare #order int = 3;
declare #limit int = 50000;
with nos as (select 1 no
union all
select no + 1 from nos where no < #limit),
cte as (select no as x, substring(cast(no as nvarchar(40)) ,1,1) as u, 1 as N FROM nos
union all
select x, substring(cast(x as nvarchar(40)),n+1,1) as u , n+1 from cte where len(cast(x as nvarchar(40))) > n
)
select x from cte group by x having SUM(POWER(cast(u as int),#order)) = x
option (maxrecursion 0);
This is a quick mod to my sum of digits UDF
Declare #Table table (Numbers int)
Insert into #Table values
(121),
(113),
(423),
(153),
(541),
(371)
Select * from #Table where [dbo].[udf-Stat-Is-Armstrong](Numbers)=1
Returns
Numbers
153
371
The UDF
CREATE Function [dbo].[udf-Stat-Is-Armstrong](#Val bigint)
Returns Bit
As
Begin
Declare #RetVal as bigint
Declare #LenInp as bigint = len(cast(#Val as varchar(25)))
;with i AS (
Select #Val / 10 n, #Val % 10 d
Union ALL
Select n / 10, n % 10
From i
Where n > 0
)
Select #RetVal = IIF(SUM(power(d,#LenInp))=#Val,1,0) FROM i;
Return #RetVal
End
You can use the following to find Armstrong numbers using Sql functions:
WITH Numbers AS(
SELECT 0 AS number UNION ALL SELECT number + 1 FROM Numbers WHERE number < 10000)
SELECT number AS ArmstrongNumber FROM Numbers
WHERE
number = POWER(COALESCE(SUBSTRING(CAST(number AS VARCHAR(10)),1,1),0),3)
+ POWER(COALESCE(SUBSTRING(CAST(number AS VARCHAR(10)),2,1),0),3)
+ POWER(COALESCE(SUBSTRING(CAST(number AS VARCHAR(10)),3,1),0),3)
OPTION(MAXRECURSION 0)

In SQL , how to build a loop that copies a row number of times

could someone please help? My starting table looks like this with 2 fields:
Name Counter
dave 2
Joe 3
I want my result to look like this:
Name Counter
dave 1
dave 2
joe 1
joe 2
joe 3
Essentially creating n number of records base on the counter and starts at 1. I tried to do a loop using counter as a variable, but the code just runs nonstop.. could someone help?
A procedural SQL Server solution:
declare #input table
(
name nvarchar(100)
,wantedrows int
,processed bit
,id uniqueidentifier
);
declare #output table
(
name nvarchar(100)
,rownum int
);
insert into #input
select 'Dave',3,0,newid()
union
select 'Joe',2,0,newid();
while exists(select * from #input where processed = 0)
begin
declare #currentid uniqueidentifier = (select top 1 id from #input where processed = 0);
declare #currentwantedrows int = (select wantedrows from #input where id = #currentid);
declare #i int = 0;
while #i < #currentwantedrows
begin
insert into #output
select name,#i+1
from #input
where id = #currentid;
set #i = #i + 1;
end;
update #input set processed = 1 where id = #currentid;
end
select name,wantedrows from #input;
select * from #output;
You can use a number-table or following trick using a system view to build a sequence:
WITH Nums AS
(
SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects
)
SELECT Name, Counter = n
FROM Nums n CROSS JOIN Table1 t1
WHERE n BETWEEN 1 AND Counter
ORDER BY Name, Counter;
Demo
This view has only about 2000 rows, so if you need more you could use a number-table.
http://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1
( presuming SQL-Server )
Is a hundred copies enough?
create table #c (num)
insert into #c (num)
select 0 union
select 1 union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9
select T.Name, c1.num * 10 + c0.num + 1
from T, #c c1, #c c0
where c1.num * 10 + c0.num < T.Counter
drop table #c
You didn't say which version of Sybase. The old ones I've worked on didn't allow derived tables so I had to throw the values into a temp table. But you can see how to extend the idea. This may not be the best approach if this is something you need to do more than once though.

SQL Server solution to simple recursive function

I am looking for a SQL Server solution for a simple recursive formula. In the example, X is my column of numbers and Y is the column I am trying to create with a SQL Query.
I have a list of numbers, denoted X, and wish to produce a special kind of running sum that is not allowed to go less than 0, denoted Y.
Base Case
Y1 = MAX(X1,0)
Recursive Rule
Yi = MAX(Xi+Yi-1,0)
EXAMPLE:
id X(Input) Y(Output)
1 15 15
2 -87 0
3 26 26
4 -87 0
5 4 4
6 -19 0
7 34 34
8 -4 30
9 40 70
10 -14 56
Assuming you have an id column that specifies the ordering, I am pretty sure you have to do this with a recursive CTE. The problem is that the "set negative numbers to zero" complicates the situation.
Let me assume that the id identifies the ordering.
with t as (
select t.*, row_number() over (order by id) as seqnum
from table t
),
cte as (
select X,
(case when X < 0 then 0 else X end) as Y
from t
where id = 1
union all
select tnext.X,
(case when tnext.X + cte.Y < 0 then 0 else tnext.X + cte.Y end) as Y
from cte join
t tnext
on t.id + 1 = tnext.id
)
select *
from cte;
Using a cursor and a table variable to catch the calculated values might be good for performance.
declare #T table
(
id int,
X int,
Y int
);
declare #id int;
declare #X int;
declare #Y int;
set #Y = 0;
declare C cursor local static forward_only read_only for
select T.id, T.X
from T
order by T.id;
open C;
fetch next from C into #id, #X;
while ##fetch_status = 0
begin
set #Y = case when #X + #Y < 0 then 0 else #X + #Y end;
insert into #T(id, X, Y) values (#id, #X, #Y);
fetch next from C into #id, #X;
end
close C;
deallocate C;
select T.id, T.X, T.Y
from #T as T
order by T.id;
SQL Fiddle
Have a look at Best approaches for running totals by Aaron Bertrand