SQL query for printing n rows [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I need a query which prints rows by the n number represented against it. example

You haven't specified your DBMS, the following solution will work for PostgreSQL:
select t.nr
from generate_series(1,4) as t(nr)
cross join generate_series(1,t.nr)
order by t.nr;
With 100% standard ANSI SQL, you can do this:
with recursive numbers (nr) as (
select * from (values (1) ) as t
union all
select p.nr + 1
from numbers p
where p.nr + 1 <= 4
)
select t.*
from numbers t
join numbers t2 on t2.nr <= t.nr
order by t.nr;

SQL Server
declare #n int = 5; // your n value
declare #i int = 1;
declare #j int = 1;
declare #tmp table (val int)
WHILE (#i <= #n)
BEGIN
WHILE (#j <= #i)
BEGIN
insert into #tmp(val) values(#i)
set #j = #j + 1;
END
set #j = 1;
set #i = #i + 1;
END
select * from #tmp

Related

I have to update 40 million rows in SQL Server [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 1 year ago.
Improve this question
The code shown here is taking a very long time to update or populate 42673844. Could anyone help me on how to simplify this code and improve the performance.
I am trying to populate the Session ID's based on some conditions
Declaration of variables
declare #sval as INT
declare #maxRow as INT
declare #currvlt as int
declare #prevvlt as int
declare #cashamount as int
declare #sec as INT
declare #next_action as INT
declare #previous_action as INT
declare #rec as int
declare #currentRow as INT
-- assigning the maximum value to the #maxrow
set #maxRow = (select max(number) from dbo.stage3 as count)
print #maxRow
set #sval = 0
set #currentRow = 1
I am putting the conditions in a while loop to perform an update all the 42 million rows. The below select will assign the values to the declared variables
While (#currentRow <= #maxRow)
begin
select
#currvlt = vltid ,
#prevvlt = previous_vltid ,
#cashamount = isnull(playercashableamount,0),
#sec = seconds,
#next_action = next_action , --next record type
#previous_action = previous_action,
#rec = recordtype
from dbo.stage3
where number = #currentRow
if #currvlt <> #prevvlt or #prevvlt is null
begin
update dbo.stage3 set sessionid = #sval+1 where number = #currentRow
set #sval = #sval +1
end
else
if (#rec = '4' and #sec > 30 and #previous_action in( 1 ,5)) or
(#cashamount < 1 and #sec < 30 and #next_action in( 1 ,4 )) or
((#rec = '5' and #sec < 30 and #next_action = '4' ) or
#next_action = '4')
begin
update dbo.stage3 set sessionid = #sval where number = #currentRow
end
else
update dbo.stage3 set sessionid = #sval where number = #currentRow
set #currentRow = #currentRow +1
end
This might help. You should not need to do a row by row evaluation. Instead, address the entire set in one call when possible. Since you have provided no information about the business challenge you are trying to solve, this code is posted as-is. This may not be exactly what you're after, but it should get you going in the right direction. Please adjust for your own needs.
Also, any update on a table with 40 million rows will take a long time; even if you have perfectly tuned indexes on lightning fast storage. Instead of thinking "how do I get the answer I want?", try thinking "what am I asking the server to do for me?", and "is there a better way to make this request?" SQL Server runs best when dealing with a set of data in one pass. Analyzing row by row is not what the engine is built to do. It can be done, but should be used only when all other means have been exhausted.
The code below is a select statement. Run it, and if the results are what you're looking for, uncomment the UPDATE section, then comment out the SELECT section and run it.
SELECT CASE
WHEN recordtype = '4'
AND seconds > 30
AND previous_action IN (1, 4) THEN 0
WHEN s.cash_amount < 1
AND seconds < 30
AND next_action IN (1, 4) THEN 0
WHEN next_action = 4 THEN 0
WHEN (vltid <> previous_vltid)
OR previous_vltid IS NULL THEN s.RowNum
ELSE s.RowNum
END AS session_id
,s.vltid
,s.previous_vltid
,s.cash_amount
,s.recordtype
,s.previous_action
,s.seconds
,s.next_action
--UPDATE s
--SET sessionid = CASE
-- WHEN recordtype = '4'
-- AND seconds > 30
-- AND previous_action IN (1, 4) THEN 0
-- WHEN s.cash_amount < 1
-- AND seconds < 30
-- AND next_action IN (1, 4) THEN 0
-- WHEN next_action = 4 THEN 0
-- WHEN (vltid <> previous_vltid)
-- OR previous_vltid IS NULL THEN s.RowNum
-- ELSE s.RowNum
-- END
FROM (
SELECT sessionid
,ROW_NUMBER() OVER (PARTITION BY vltid
ORDER BY
vltid
) AS RowNum
,vltid
,previous_vltid
,ISNULL(playercashableamount, 0) AS cash_amount
,recordtype
,previous_action
,seconds
,next_action
FROM dbo.stage3
) AS s;

Best practice to handle the paging and performance in SQL Stored procedure [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 3 years ago.
Improve this question
I am using MS SQL stored procedure to retrieve data and display it in the GRID. My problem is that the stored procedure has complex queries and it returns a total of 12K records. But in the grid am exposing 1st 50 records only.
I have used SQL fetch and offset concept to avoid the unwanted data but I want the total count to display it in the grid.
Can you please suggest any better solution to handle this?
In global you can build such a structure:
create PROCEDURE your_sp
#PageNumber INT = 1,
#PageSize INT = 10,
DECLARE #lPageSize INT= #PageSize;
DECLARE #lFirstRecord INT= (#lPageNumber - 1) * #lPageSize;
DECLARE #lLastRecord INT= (#lPageNumber * #lPageSize + 1);
CREATE TABLE #tmp (...)
INSERT INTO #tmp (
select * from
(... your sub select heer)
WHERE ROWNUM > #lFirstRecord
AND ROWNUM < #lLastRecord
)
-- Count all results in temporary table
DECLARE #COUNT BIGINT;
SET #COUNT =
(
SELECT COUNT(*)
FROM #tmp
);
-- Apply paging to temporary table, and output results
SELECT
*,
#COUNT [Count]
FROM #tmp
WHERE ROWNUM > #lFirstRecord
AND ROWNUM < #lLastRecord
ORDER BY ROWNUM ASC;
DROP TABLE #tmp;

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 generate Fibonacci Series [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 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

Dynamic WHERE clauses in SQL Query [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to execute this query
select * from locations where region=1 or region=2
but in certain cases I don't want to include the second clause in the WHERE (or region=2)
Is there a way to conditionally run the or statement?
Check for the condition in the where statement
select * from locations
where region=1
or (region=2 and #checkRegion2=1)
If you want genralizable query, you can declare table variable for this (I assuming you're using SQL server):
declare #regions table (id int primary key)
and then fill it depending on condition:
insert into #regions select 1
if #use2 = 1
insert into #regions select 2
now you can run this query:
select *
from location as l
where exists (select * from #regions as r where r.id = l.region)
or
select *
from location as l
where l.region in (select r.id from #regions as r)
DECLARE #RUNAFTERBIT VARCHAR(10)
SET #RUNAFTERBIT = 'TRUE'
IF #RUNAFTERBIT = 'TRUE'
SELECT * FROM LOCATIONS WHERE REGION = 1 OR REGION = 2
ELSE
SELECT * FROM LOCATIONS WHERE REGION = 1
END IF
You can use dynamic SQL:
DECLARE #Query VARCHAR(MAX) = 'SELECT * FROM locations WHERE region=1 '
IF(#RUNAFTERBIT = 'TRUE')
BEGIN
SET #Query = #Query + ' OR REGION = 2'
END
EXEC(#Query)
A CASE expression can be used to perform short circuit evaluation under some circumstances:
declare #AlternateRegion as Int = 2;
select *
from Locations
where case
when Region = 1 then 1
when #AlternateRegion is not NULL then
case when Region = #AlternateRegion then 1 else 0 end
else 0
end = 1
CASE does not reliably provide short circuit evaluation in the presence of aggregation functions. See CASE / COALESCE won't always evaluate in textual order
and Aggregates Don't Follow the Semantics Of CASE
.