creating table and using if statement - sql-server

I have this question which I don't really understand
I need help understanding or answering it

--Create the table on the fly with the condition stated
SELECT
TEAM_NAME,
RACES_COMPETED
INTO [TOP TEAMS]
FROM YourTable
WHERE RACES_COMPETED >= 500 and RACES_COMPETED <= 900
--Store the number of teams in the new table in a variable for ease of use
DECLARE #topTeams INT
SET #topTeams = (SELECT COUNT(*) FROM [TOP TEAMS])
--If there are teams in the table, print the number of teams. If there aren't any, print the other statment
IF #topTeams > 0
BEGIN
SELECT 'NO. OF TOP TEAMS: ' + CAST(#topTeams AS VARCHAR)
END
ELSE
BEGIN
SELECT 'NO TOP TEAMS EXIST'
END
HERE IS THE SAME CODE USING A TEMP TALBE
--Drop the TEMP TABLE if it exists
IF OBJECT_ID('tempdb..#TOP_TEAMS') IS NOT NULL DROP TABLE #TOP_TEAMS
--Create the table on the fly with the condition stated
SELECT
TEAM_NAME,
RACES_COMPETED
INTO #TOP_TEAMS
FROM YourTable
WHERE RACES_COMPETED >= 500 and RACES_COMPETED <= 900
--Store the number of teams in the new table in a variable for ease of use
DECLARE #topTeams INT
SET #topTeams = (SELECT COUNT(*) FROM #TOP_TEAMS)
--If there are teams in the table, print the number of teams. If there aren't any, print the other statment
IF #topTeams > 0
BEGIN
SELECT 'NO. OF TOP TEAMS: ' + CAST(#topTeams AS VARCHAR)
END
ELSE
BEGIN
SELECT 'NO TOP TEAMS EXIST'
END

Related

Converting SQL Server script to Oracle

I have a script that I created that works fine in SQL Server, but now I need to make it work in Oracle and I am having issues getting the script converted.
Here is my SQL Server Script:
-- run the commented out statement in another query analyzer window to stop the script
-- update ##stopsign set val = 1
set nocount on
--declare variables
declare #morework int
declare #archivecount int
declare #stopsign int
--if working tables exists clear them, if not create and initialize them
if (object_id('tempdb..##stopsign') is null)
create table ##stopsign (val int)
else
delete from ##stopsign
insert into ##stopsign values (0)
if (object_id('tempdb..#tempdins') is null)
create table #tempdins (tempdin varchar(255) not null, processed int null)
else
delete from #tempdins
--initialize #tempdins working table with all the records eligible to be unarchived
--edit the select statement if needed to change the records to be unarchived
insert into #tempdins(tempdin)
select tempdin
from document
where archivestatus = 'C'
and status = 'U'
option (MAXDOP 1)
--inialize variables with current values
select #archivecount = (select count(*) from unarchs)
select #stopsign = (select val from ##stopsign)
select #morework = 1
--while there is more to do, unarchs table has less then 1000 records, and the stopsign value is 0 loop
while (#morework >= 1 and #stopsign = 0)
begin
if #archivecount <1000
begin
-- number to be processed at once
-- change this value if you would like to dump more in to the unarchs table at once
set rowcount 100
update #tempdins
set processed = 0
where processed is null
--reset rowcount
set rowcount 0
--populate the unarchs table with valid values
--this will unarchive at the page (lowest) level
insert into unarchs (drawer,foldernumber,packageid,docid,pagenumber,unarchtype,unarchdate,unarchtime,userid,unarchdays)
select distinct drawer,foldernumber,packageid,docid,pagenumber,'Page','20061128','12:00:00','ADMIN',360
from document
where tempdin in (select tempdin
from #tempdins
where processed = 0)
--update with rowcount to see if finished
select #morework = ##rowcount
--set the tempdins to processed in working table
update #tempdins
set processed = 1
where processed = 0
--get new counts for variables for evaulation
select #archivecount = (select count(*) from unarchs)
select #stopsign = (select val from ##stopsign)
--wait a second so the CPU doesn't spin
waitfor delay '00:00:01'
end
else
begin
--get new counts for variables for evaulation
select #archivecount = (select count(*) from unarchs)
select #stopsign = (select val from ##stopsign)
--wait a second so the CPU doesn't spin
waitfor delay '00:00:01'
end
end
set nocount off
Here is what I have for ORACLE so far (writing in PL/SQL):
-- run the commented out statement in another query analyzer window to stop the script
-- update ##stopsign set val = 1
--if working tables exists clear them, if not create and initialize them
declare
v_sql LONG;
begin
v_sql:='CREATE GLOBAL TEMPORARY TABLE STOPSIGN;
(
VAL int
)';
execute immediate v_sql;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -955 THEN
NULL; -- suppresses ORA-00955 exception
ELSE
delete from STOPSIGN;
END IF;
END;
/
insert into STOPSIGN values (0);
--if working tables exists clear them, if not create and initialize them
declare
v_sql LONG;
begin
v_sql:='CREATE GLOBAL TEMPORARY TABLE TEMPDINS;
(
tempdin varch(255),
processed int null
)';
execute immediate v_sql;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -955 THEN
NULL; -- suppresses ORA-00955 exception
ELSE
delete from TEMPDINS;
END IF;
END;
/
--initialize #tempdins working table with all the records eligible to be unarchived
--edit the select statement if needed to change the records to be unarchived
insert into TEMPDINS(tempdin)
select * from (select tempdin
from document join packtype on packtype.packagetype=document.packagetype
and archivestatus = 'C' and ADRIVE is not null
and ADRIVE <> DRIVE ) where ROWNUM < 10;
--inialize variables with current values
Declare
archivecount int;
stopsign int;
morework int;
Begin
Select count(*) INTO archivecount from UNARCHS;
Select VAL into stopsign from STOPSIGN;
morework := 1;
END
--while there is more to do, unarchs table has less then 1000 records, and the stopsign value is 0 loop
WHILE morework > 0 and stopsign = 0
LOOP{
begin
if archivecount <1000
begin
-- number to be processed at once
-- change this value if you would like to dump more in to the unarchs table at once
set rowcount 100
update TEMPDINS
set processed = 0
where processed is null
}
--reset rowcount
set rowcount 0
--populate the unarchs table with valid values
--this will unarchive at the page (lowest) level
insert into UNARCHS (drawer,foldernumber,packageid,docid,pagenumber,unarchtype,unarchdate,unarchtime,userid,unarchdays)
select distinct drawer,foldernumber,packageid,docid,pagenumber,'Page','20061128','12:00:00','ADMIN',360
from DOCUMENT
where tempdin in (select tempdin
from TEMPDINS
where processed = 0)
--update with rowcount to see if finished
select morework = select NUM_ROWS into morework from user_tables where table_name = 'UNARCHS'
--set the tempdins to processed in working table
update TEMPDINS
set processed = 1
where processed = 0
--get new counts for variables for evaulation
select archivecount = (select count(*) from unarchs)
select stopsign = (select val from STOPSIGN)
--wait a second so the CPU doesn't spin
waitfor delay '00:00:01'
end
else
begin
--get new counts for variables for evaulation
select archivecount = (select count(*) from unarchs)
select stopsign = (select val from STOPSIGN)
--wait a second so the CPU doesn't spin
waitfor delay '00:00:01'
end
end
End
END IF
END LOOP
Any help would be appreciated. My company has no Oracle resources for me to go to and Google is getting tired of me.
I think you can get rid of everything and just do a single insert statement:
insert into unarchs (drawer,foldernumber,packageid,docid,pagenumber,unarchtype,unarchdate,unarchtime,userid,unarchdays)
select distinct drawer,foldernumber,packageid,docid,pagenumber,'Page','20061128','12:00:00','ADMIN',360
from DOCUMENT
where archivestatus = 'C'
And status = 'U';
I’m assuming you have a different process that updates the rows in the document table so this process doesn’t constantly pick up the same rows?

Multiple procs execution using row count in sql server

I have a proc in which I need to execute 4 different query based on the condition if the result from 1st query is 0 then it should execute the 2nd query and so on
I am using the ##RowCount to find the row count and then passing the value. Here is my code:
ALTER PROCEDURE FetchingValues #StartLocation Varchar(200),#EndLocation Varchar(200)
AS
DECLARE
#Count NUMERIC
BEGIN
if ##ROWCOUNT=0
BEGIN
select DISTINCT TOP 1 t1.Train_No,Max(t1.Distance) as TotalDistance,0 as Waiting_Time
from Rail t1
where t1.Source_Station_Name Like #StartLocation+'%'
and t1.Destination_Station_Name Like #EndLocation+'%'
GROUP BY t1.Train_No
Order BY TotalDistance ASC
SET #Count= (SELECT ##ROWCOUNT)
SELECT ##ROWCOUNT
END
ELSE if #Count <> 1
BEGIN
EXEC Connection1 #StartLocation,#EndLocation
SET #Count=(SELECT ##ROWCOUNT)
SELECT ##ROWCOUNT
END
ELSE if #Count <> 1
BEGIN
EXEC Connection2 #StartLocation,#EndLocation
SET #Count=(SELECT ##ROWCOUNT)
SELECT ##ROWCOUNT
END
ELSE
BEGIN
select DISTINCT TOP 1 (t1.Train_No+','+ t2.Train_No+','+t3.Train_No+','+t4.Train_No) as TrainSeq,
Max(t1.Distance)+Max(t2.Distance)+Max(t3.Distance)+Max(t4.Distance)as TotalDistance
from Rail t1
join Rail t2 on (t2.Source_Station_Name=t1.Destination_Station_Name)
Join Rail t3 on (t3.Source_Station_Name=t2.Destination_Station_Name)
Join Rail t4 on (t4.Source_Station_Name=t3.Destination_Station_Name)
where t1.Source_Station_Name Like #StartLocation+'%'
and t2.Destination_Station_Name Like #EndLocation+'%'
Group by t1.Train_No,T2.Train_No,t3.Train_No,t4.Train_No
ORDER BY TotalDistance ASC
END
I want to execute the query by passing 2 values then I should check through all the queries and should get the output
If you need to suppress empty resultsets then there is only one way - insert exec into temp table and check whethere there is anything or not. If there are records - no need to run next queries, just select from #.
BEGIN
select DISTINCT TOP 1 t1.Train_No,Max(t1.Distance) as TotalDistance,0 as Waiting_Time
into #t -- <<<<<<
from Rail t1
where t1.Source_Station_Name Like #StartLocation+'%'
and t1.Destination_Station_Name Like #EndLocation+'%'
GROUP BY t1.Train_No
if not exists(select 1 from #t)
BEGIN
insert #t
EXEC Connection1 #StartLocation,#EndLocation
END
if not exists(select 1 from #t)
BEGIN
insert #t
EXEC Connection2 #StartLocation,#EndLocation
END
if not exists(select 1 from #t)
...
/* finally */
select * from #t
Order BY TotalDistance ASC
END

COUNT in CASE - SQL Server

Is it possible to do a value assignment with a COUNT() as the when clause?
Like so:
SELECT #value =
CASE
WHEN
COUNT(tableID)
FROM (SELECT TOP (5) tableID FROM table) AS id = 20
THEN 'Looks Good'
END
I basically what to select a variable amount of rows [TOP (#rowCount)], then take action based on the number of rows counted. I'm sure I can do this someway somehow, guessing I'm just missing something in the syntax.
If you're looking for code branching, the following would work:
IF 20 = (select count(*)
from (select top (5) tableID from table) as id)
PRINT 'Looks Good'
ELSE
PRINT '5 will never equal 20'
If you want to get or set a value, one of the following would work:
SELECT case count(*)
when 20 then 'good'
else 'bad'
end
from (select top (5) tableID from table) as id
or
SELECT case
when count(*) > 5 then 'Over 5'
when count(*) < 5 then 'Under 5'
else 'Exactly 5'
end
from (select top (5) tableID from table) as id
Not sure if I understand the question, but maybe try something like
select #val = case when the_number >= 20 then 'Looks good' end
from (
select count(*) the_number from some_table
) x
Assuming you are using at least sql2005 or greater then this will work -
--create a table to test with
create table #TestTable
(
TestTableID int primary key
)
--populate test table
declare #i int = 0;
while #i < 10
begin
insert into #TestTable select #i;
set #i = #i + 1;
end
GO
--now create variables to hold the TOP value and to store the result
declare #a int = 5
,#value varchar(10);
--correct case stmt syntax
set #value = case
when (select count(RecordList) as 'RecordListCount' from (select top (#a) TestTableID as 'RecordList' from #TestTable) as sq) = 20 then 'Looks Good'
else 'Looks Bad'
end;
select #value;
Remember to put the TOP variable in parentheses and to supply aliases for all of the tables and columns.
I hope that helps!
I think I understood your question. You want to know if it is possible to have TOP N rows of table, when N is variable.
If I am right, you will need to specify a column which the table would be ordered.
Then you can use something like:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY COLUMN_NAME) TOPCOL
FROM TABLE_NAME
) A
WHERE TOPCOL <= N
If I am not right, you should edit your question, because it is very hard to understand what you meant

Update row with condition in SQL Server 2008

This is my table structure:
CREATE table Credit(id integer, organisationid int, availableCredit int)
INSERT INTO Credit VALUES (1, 1, 1000)
INSERT INTO Credit VALUES (2, 1, 100)
INSERT INTO Credit VALUES (3, 2, 600)
INSERT INTO Credit VALUES (4, 2, 400)
I have to reduce the available credit column value, I have amount 1050 with me. I need to reduce 1050 from credit table where organisation id = 1. Here the organisation Id 1 have 1100 available credit in total. The condition is the first inserted credit row should be updated first and then the rest (FIFO model), also the updation should happen only for organisationId = 1.
How do we update this using a single or multiple update statement?
Any suggestions?
Unfortunately, this is a rather messy thing to do in T-SQL - you'll need something like a loop (cursor or WHILE statement).
With this code here, I can get it to run - it's not pretty, but it works.
-- you want to reduce the total credits by this amount
DECLARE #AmountToReduce INT = 1050
-- temporary variables
DECLARE #ID INT, #AvailableCredit INT
-- get the first row from dbo.Credit that still has availableCredit - ordered by id
SELECT TOP 1 #ID = id, #AvailableCredit = availableCredit
FROM dbo.Credit
WHERE availableCredit > 0 AND organisationId = 1
ORDER BY id
-- as long as we still have credit to reduce - loop..
WHILE #AmountToReduce > 0 AND #ID IS NOT NULL
BEGIN
-- if we need to remove the complete availableCredit - do this UPDATE
IF #AmountToReduce > #AvailableCredit
BEGIN
UPDATE dbo.Credit
SET availableCredit = 0
WHERE id = #ID
SET #AmountToReduce = #AmountToReduce - #AvailableCredit
END
ELSE BEGIN
-- if the amount to reduce left is less than the availableCredit - do this UPDATE
UPDATE dbo.Credit
SET availableCredit = availableCredit - #AmountToReduce
WHERE id = #ID
SET #AmountToReduce = 0
END
-- set #ID to NULL to be able to detect that there's no more rows left
SET #ID = NULL
-- select the next "first" row with availableCredit > 0 to process
SELECT TOP 1 #ID = id, #AvailableCredit = availableCredit
FROM dbo.Credit
WHERE availableCredit > 0 AND organisationId = 1
ORDER BY id
END
This script reduces "Id 1" availableCredit by 1000, and reduces "Id 2" availableCredit by 50.
UPDATE Credit
SET availableCredit=(availableCredit-1000)
WHERE id=1
UPDATE Credit
SET availableCredit=(availableCredit-50)
WHERE id=2
Previously I had given only select query,Here is the final UPDATE query which does the task.
DECLARE #balance int=1050
;WITH CTE as (
select id,organisationid,CASE when #balance>availableCredit then 0 else availableCredit-#balance end as availableCredit,
CASE when #balance>availableCredit then #balance-availableCredit else 0 end as balamt from Credit where id=1 and organisationid=1
union all
select t.id,t.organisationid,CASE when c.balamt>t.availableCredit then 0 else t.availableCredit-c.balamt end as availableCredit,
CASE when c.balamt>t.availableCredit then c.balamt-t.availableCredit else 0 end as balamt1
from Credit t inner join CTE c on t.id-1=c.id --and t.organisationid=1
)
Update c SET c.availableCredit = ct.availableCredit
FROM Credit c inner join CTE ct
on c.id=ct.id
SELECT * FROM Credit
Try This query:
CREATE table Credit(id integer, organisationid int, availableCredit int)
INSERT INTO Credit VALUES (1, 1, 1000)
INSERT INTO Credit VALUES (2, 1, 100)
INSERT INTO Credit VALUES (3, 2, 600)
INSERT INTO Credit VALUES (4, 2, 400)
DECLARE #balance int=1050
;WITH CTE as (
select id,organisationid,CASE when #balance>availableCredit then 0 else availableCredit-#balance end as availableCredit,
CASE when #balance>availableCredit then #balance-availableCredit else 0 end as balamt from Credit where id=1 and organisationid=1
union all
select t.id,t.organisationid,CASE when c.balamt>t.availableCredit then 0 else t.availableCredit-c.balamt end as availableCredit,
CASE when c.balamt>t.availableCredit then c.balamt-t.availableCredit else 0 end as balamt1
from Credit t inner join CTE c on t.id-1=c.id and t.organisationid=1
)
SELECT id,organisationid,availableCredit FROM CTE

TSQL calculating sum of numerous fields

I have this kind of data:
Date Count1 Count2 Count3 ... Countxx
01-05-2012 1 0 1 2
01-05-2012 2 1 3 0
01-05-2012 2 3 3 1
02-05-2012 1 3 2 0
02-05-2012 5 2 0 0
and I need to calculate sum of respective fields (Count1 to Countxx) grouped by date and wrote this SQL:
select sum(count1), sum(count2), sum(count3), .. , sum(countxx)
from table1 group by date
my first question: is there any way in SQL server to do this automatically (without knowing number of fields, since the name and number of the fields will be different each time, thus making writing the SQL manually very cumbersome).
secondly, how to calculate value from current row minus previous row, and average of previous 7 rows?
Thanks!
create procedure USP_FindSum #tablename varchar(100)
as
begin
create table #temp(id int identity(1,1),name varchar(100))
declare #sqlcmd nvarchar(max)=''
SET #sqlcmd= N'Insert into #temp select name from sys.columns col_table where
col_table.object_id=object_id('''+#tablename+''')'
EXEC sp_executesql #sqlcmd
declare #sqlseg varchar(max)=''
declare #tempcount int
declare #i int=1
select #tempcount=COUNT(id) from #temp
while(#i<=#tempcount)
BEGIN
declare #CName varchar(100)
SELECT #CName= name from #temp where id=#i
if(#i!=#tempcount)
SET #sqlseg=+#sqlseg+'sum('+#CName+')'+','
else
SET #sqlseg =+#sqlseg+'sum('+#CName+')'
SET #i=#i+1
END
SET #sqlcmd=N'select '+#sqlseg+' from '+#tablename
EXEC sp_executesql #sqlcmd
DROP TABLE #temp
END
Assuming all the columns in the table are summable. As your requirement is weird this workaround may also be so.
Just pass the table name as parameter and execute,
Exec USP_FindSum '<tablename here>'
There is no way to sum a variable list of columns, you have to specify them all.
One way to look up the previous row is outer apply, like:
select Date
, cur.count1 - isnull(prev.count1,0) as Delta1
from Table1 cur
outer apply
(
select top 1 *
from Table1 prev
where prev.Date < cur.Date
order by
prev.Date desc
) prev
Another way is to join the tables based on row_number():
; with t1 as
(
select row_number() over (order by Date) as rn
, *
from Table1
)
select Date,
, cur.count1 - isnull(prev.count1,0) as Delta
from t1 cur
left join
t1 prev
on cur.rn = prev.rn + 1

Resources