How do I make recursion in SQL only with select? - sql

Is there a way to have a recursion in Oracle SQL only using select statements?
For example how do I sum a column in a table without using sum()?

The answer to this question demonstrates recursion in Oracle, for both recursive CTEs (Oracle 11 onwards) and Oracle's own CONNECT BY syntax (Oracle 10g and earlier).

create table #temp (
id int,
value int)
insert into #temp values (1, 1)
insert into #temp values (2, 2)
insert into #temp values (3, 3)
declare #sum int
declare #biggest int
select #biggest = max(id) from #temp
select #sum = 0
while #biggest != 0
begin
select #sum = #sum + value from #temp where id = #biggest
select #biggest = #biggest - 1
end
select #sum

Related

dynamic alias in sql server

I want query field with different alias in stored procedure
select COUNT(EmpCode) as CountEmp+#para
result shoud be
CountEmp1
45
CountEmp2
54
CountEmp1
76
Query loop in c# code:
select COUNT(EmpCode) where something = #something as CountEmp+#para
Approach without dynamic SQL:
--I create temp table for demonstration
DECLARE #some_table TABLE (
Something int,
EmpCode INT
)
INSERT INTO #some_table (Something, EmpCode)
VALUES (1, 10),(1, 22),(1, 12),(2, 12),(2, 30),(3, 65),(3, 15),(3, 11),(3, 5)
--Declare parameter we want to search
DECLARE #param int = 1
--Query
--In cte we select what we need based on parameter
;WITH cte AS (
SELECT 'CountEmp'+CAST(#param as nvarchar(10)) as SomeThing,
CAST(COUNT(EmpCode) as nvarchar(10)) as EmpCodeCount,
ROW_NUMBER() OVER (ORDER BY SomeThing ) as rn
FROM #some_table
WHERE SomeThing = #param
GROUP BY SomeThing
)
--And here comes UNION
SELECT SomeThing as Result
FROM (
SELECT SomeThing,rn
FROM cte
UNION ALL
SELECT EmpCodeCount ,rn
FROM cte
) as t
ORDER BY rn, SomeThing DESC
Output:
Result
------------------
CountEmp1
3
(2 row(s) affected)
Please try to make use of below code. Its working fine with SQL Server 2012.
IF OBJECT_ID ('temp..#Mytable') IS NOT NULL
CREATE TABLE #Mytable (ID INT IDENTITY (1,1),EmpCode INT)
DECLARE #max int ,#count int
SET #max =0;
DECLARE #str varchar(10)
INSERT #Mytable
(EmpCode)
VALUES
(10),
(45),
(35),
(63),
(56),
(65)
SET #count = (SELECT COUNT (ID) FROM #Mytable )
WHILE #count > #max
BEGIN
SET #max = #max+1
SET #str = CONVERT(varchar(10),#max)
EXEC('SELECT EmpCode AS Empcode'+#str+ ' FROM #Mytable WHERE ID = '+#str)
END

How to insert values in temp table on multiple times

I have this code. Can I insert values into a temp table multiple times? I have list of ids (i.e. 1000 ids). I want to insert this by loop.
DECLARE #tempTable TABLE(col1 INT)
FOR (#ids IS NOT NULL) {
INSERT INTO #tempTable VALUES(#ids)
}
SELECT * FROM #tempTable
Even though it is possible using WHILE loop I will suggest you to go with SET Based approach
Why cant you just do this
INSERT INTO #tempTable (ID)
select Id from yourlist
SQL Server is not support FOR loop. You need to use WHILE loop instead.
SQL Server Looping
You can use a while statement as said Jitendra Tiwari:
DECLARE #tempTable TABLE(col1 INT)
DECLARE #num int
SET #num = 1
WHILE #num <= 1000
BEGIN
INSERT INTO #tempTable VALUES (#num) --(#ids)
SET #num = #num + 1
END
SELECT * FROM #tempTable

T-SQL find only the columns which can be casted as INT

I need to write an SELECT statement, that has a WHERE clause, where only the rows that can be CAST as INT will be selected, not BIGINT, but INT.
Is that possible
I am on SQL Server 20**
Right now I am doing something like this:
SELECT CAST(column as INT) FROM TABLE
WHERE ISNUMERIC(column) = 1
But then I get 'The conversion of the varchar value '275949275947' overflowed an int column'
There is alot of different data in the column - but I only need the INTs
SQL Server 2012:
select try_parse('1231321313' as int)
select try_parse('234242342341231321' as int)
SQL Server < 2012:
select case when ISNUMERIC('1231321313') = 1
and patindex('%[^0-9-]%', '1231321313') = 0
and cast('1231321313' as bigint) between -2147483648 and 2147483647
then cast('1231321313' as int) end
select case when ISNUMERIC('234242342341231321') = 1
and cast('234242342341231321' as bigint) between -2147483648 and 2147483647
then cast('234242342341231321' as int) end
edit: to deal with potential currency values ('$23424231321', '€23424231321' etc) you could also add patindex('%[^0-9-]%', '1231321313') = 0
DECLARE #Table TABLE (
[column] VARCHAR(200)
)
INSERT INTO #Table SELECT '1'
INSERT INTO #Table SELECT '154674'
INSERT INTO #Table SELECT '-2147483649'
INSERT INTO #Table SELECT '2147483648'
SELECT CAST([column] as INT) FROM #TABLE
WHERE ISNUMERIC([column]) = 1
AND CAST([column] as BIGINT)>=-2147483648
AND CAST([column] as BIGINT)<=2147483647
This will work on MS SQL 2012+:
DECLARE #t TABLE ( A INT, B NVARCHAR(50) )
INSERT INTO #t
VALUES ( 1, '1' ),
( 2, '275949275947' ),
( 2, 'cc' )
SELECT CAST(B AS INT) AS B
FROM #t
WHERE TRY_PARSE(
B AS INT) IS NOT NULL
Output:
B
1

select records that one column are numbers close to 10

I have a table with 3 columns.
one of them is [Code]. I have many records on this table.
I want to select records that their [Code] are numbers close to 10 regularly
for example if select records that has [Code]=9 then select records that has [Code] = 8 etc...
This is what I implement based on your though.
If you wish near record or record-id, not value, then you can change only condition a.data to a.rid.
declare #t table (data int)
insert into #t values(1), (2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(50),(51),(52)
declare #value int = 11 , #getDatToValue int = 2
select * from
(
select * , ROW_NUMBER( ) over(order by data) rid
from #t
)
a
where
a.data between (#value - #getDatToValue) and (#value + #getDatToValue)

How to find values stored in a string not in a sql data table

For example, I have a list of values in a string:
'a', 'c', 'b', 'd'
From the data table, I got a column result like:
Result
'a'
'b'
how to write a sql which will return the values not in the table:
'c', 'd'
or
NewResult
'c'
'd'
?
It is also ok if other simple tools than sql can be used. I only need the result. Thanks!
Create FUNCTION F_SplitAsTable
(
#txt varchar(max)
)
RETURNS
#tab TABLE
(
ID Varchar(2000)
)
AS
BEGIN
declare #i int
declare #s varchar(2000)
Set #i = CHARINDEX(',',#txt)
While #i>1
begin
set #s = LEFT(#txt,#i-1)
insert into #tab (id) values (#s)
Set #txt=RIGHT(#txt,Len(#txt)-#i)
Set #i = CHARINDEX(',',#txt)
end
insert into #tab (id) values (#txt)
RETURN
END
GO
Declare #a table (Ch varchar(10))
insert into #a Values ('a')
insert into #a Values ('b')
Select s.* from dbo.F_SplitAsTable('a,b,c,d') s
left join #a a on a.Ch=s.ID
where a.Ch is NULL
Step 1: Load the search values in a temp table.
DECLARE #Search table (SearchFor char(1) not null)
INSERT #Search values ('a'), ('b'), ('c'), ('d')
(There are any number of ways to set this up, this is just the fastest to type)
Run a query like so:
SELECT SearchFor
from #Search
except select SearchIn
from DataTable
(Again, there are many forms that "in a not in b" queries can take.)
This will return everything in the first set (your temp table) that is not also found in the second set.
use the not in clause in your queries.
select myCol from myTable where myCol not in ('c','d')
select myCol from myTable where myCol not in (select myCol from otherTable)