SELECT Multiple Columns for Output in SQL Server 2012 - sql-server-2012

I have a table of stock quotes, where I loop through days to calculate a 14day RSI for a ticker:
DECLARE #StartingDate smalldatetime
DECLARE #EndingDate smalldatetime
DECLARE #FinalDate smalldatetime
DECLARE #StockID char(15)
DECLARE #DAYS INT
DECLARE #AG FLOAT(4)
DECLARE #AL FLOAT(4)
DECLARE #RS FLOAT(4)
SET #StartingDate = '20180101'
SET #FinalDate='20180405'
--SET #EndingDate = DATEADD(day, 14, #StartingDate);
SET #EndingDate = '20180403'
SET #StockID = 'ACE'
SET #DAYS = 14
WHILE (#EndingDate < #FinalDate)
BEGIN
SET #EndingDate = DATEADD(day, 13, #StartingDate);
SET #AG =(
--SELECT SUM([px_close]-[px_open])
SELECT SUM([px_close]-[px_open])
FROM [Coinmarketcap].[dbo].[daily_data]
WHERE [Ticker] = #STOCKID
AND ([Date] BETWEEN #StartingDate AND #EndingDate)
--AND ([px_close]-[px_open])>0)/#DAYS
AND ([px_close]-[px_open])>0)/#DAYS
SET #AL =(
--SELECT SUM([px_close]-[px_open])
SELECT SUM([px_close]-[px_open])
FROM [Coinmarketcap].[dbo].[daily_data]
WHERE [Ticker] = #STOCKID
AND ([Date] BETWEEN #StartingDate AND #EndingDate)
AND ([px_close]-[px_open])<0)/#DAYS
SET #RS = #AG/ABS(#AL)
SELECT #STOCKID AS [Ticker], #EndingDate AS Date, #AG AS AvGain, #AL AS AvLoss, #RS As RS, 100 - (100/(1+#RS)) RSI
SET #StartingDate = DATEADD(day, 1, #StartingDate);
END;
My loop produces RSI values for each day as individual outputs:
Ticker Date AvGain AvLoss RS RSI
ACE 2018-01-14 0.09985857 -0.07670186 1.301906 56.55773
Ticker Date AvGain AvLoss RS RSI
ACE 2018-01-15 0.1158097 -0.0737355 1.57061 61.09873
Ticker Date AvGain AvLoss RS RSI
ACE 2018-01-16 0.1150289 -0.1010219 1.138653 53.2416
How do I combine the output into one table, instead of separate tables for each date?

Related

Values are not returned for Fromdate and ToDate columns

I have created a stored procedure for bulk invoice generation. On execution of the stored procedure, the values are successfully returned for all the columns except FromDate and ToDate. For these 2 columns, NULL values are displaying.
This here is the procedure that I have created. Please let me know what I am doing wrong here?
SET #fromDt = CONVERT(VARCHAR, DATEADD(d, -(DAY(DATEADD(m, -1, #currentdate - 2))), DATEADD(m, -1, #currentdate - 1)), 106)
ALTER PROCEDURE Bulkinvoicegeneration_lko
#InvoiceMonth VARCHAR(20),
#PrjId BIGINT,
#CustomerId NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #fromDt DATETIME,
#monthdays INT,
#ToDate DATETIME,
#Currentdate DATETIME,
#Year INT
SET #currentdate = CONVERT(VARCHAR, #Year) + '-'
+ CONVERT(VARCHAR, #InvoiceMonth) + '-11'
SET #fromDt = CONVERT(VARCHAR, DATEADD(d, - (DAY(DATEADD(m, -1, #currentdate - 2))), DATEADD(m, -1, #currentdate - 1)), 106)
SET #ToDate = CONVERT(DATE, Dateadd(d, -(Day(#currentdate)), #currentdate))
SET #monthdays = DATEDIFF(d, #fromDt, #ToDate) + 1
SELECT *
INTO #consumerdata1
FROM
(SELECT
id, prjid, customerid, ucccatid, area, rate,
billingamount AS TotalAmt,
billingamount AS SubTotalAmt
FROM
consumermst_lko
WHERE
1 = 2) AS aa
BEGIN
INSERT INTO #consumerdata1
SELECT
prjid, customerid, ucccatid, area, rate,
billingamount AS TotalAmt,
billingamount AS SubTotalAmt
FROM
consumermst_lko
END
ALTER TABLE #consumerdata1
ADD invoiceno VARCHAR(20), invoicedate DATE, duedate DATE,
balanceamt NUMERIC(10, 2), roundoff NUMERIC(10, 2),
entrydate DATE, fromdate DATE, todate DATE,
userid INT, deleteflag INT, responsecode INT,
responsemessage VARCHAR(500), invoiceno_response VARCHAR(500)
UPDATE #consumerdata1
SET entrydate = Getdate()
UPDATE #consumerdata1
SET userid = 2
UPDATE #consumerdata1
SET balanceamt = 20
--update #CONSUMERDATA set billingdays = 30
UPDATE #consumerdata1
SET invoiceno = NULL,
invoicedate = CONVERT(DATE, GETDATE() - 1),
duedate = DATEADD(d, 15, CONVERT(DATE, GETDATE())),
roundoff = 0,
deleteflag = 0
DECLARE #id BIGINT,
#InvoiceNo NVARCHAR(150),
#InvoiceDate DATE,
#DueDate DATE,
#UccCatId BIGINT,
#rate NUMERIC(10, 2),
#Area NUMERIC(10, 2),
#TotalAmt NUMERIC(10, 2),
#BalanceAmt NUMERIC(10, 2),
#SubTotalAmt NUMERIC(10, 2),
#RoundOff NUMERIC(10, 2),
#EntryDate DATE,
#FromDate DATE,
#UserId BIGINT,
#deleteflag INT,
#RESPONSECODE INT,
#RESPONSEMESSAGE VARCHAR(255),
#INVOICENO_RESPONSE VARCHAR(20)
SET #prjid = 2
DECLARE consmr_cursor1 CURSOR FOR
SELECT
id, prjid, customerid, ucccatid, area, rate,
totalamt, subtotalamt, invoiceno, invoicedate, duedate,
balanceamt, roundoff, entrydate, fromdate, todate,
userid, deleteflag, responsecode, responsemessage,
invoiceno_response
FROM
#consumerdata1
OPEN consmr_cursor1
FETCH NEXT FROM consmr_cursor1
INTO #Id, #PrjId, #CustomerId, #UccCatId, #Area, #rate, #TotalAmt, #SubTotalAmt, #InvoiceNo, #InvoiceDate, #DueDate,
#BalanceAmt, #RoundOff, #EntryDate, #FromDate, #ToDate, #UserId, #deleteflag,
#ResponseCode, #ResponseMessage, #INVOICENO_RESPONSE
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC [dbo].[Demoinvoice]
#Id = #Id,
#InvoiceNo =#InvoiceNo,
#PrjId = #PrjId,
#CustomerId = #CustomerId,
#InvoiceDate = #InvoiceDate,
#InvoiceMonth = #InvoiceMonth,
#DueDate = #DueDate,
#UccCatId = #UccCatId,
#Rate = #Rate,
#Quantity = #Area,
#TotalAmt = #TotalAmt,
#BalanceAMT = #BalanceAmt,
#SubTotalAmt = #SubtotalAmt,
#RoundOff = #RoundOff,
#EntryDate = #EntryDate,
#FromDate = #FromDate,
#ToDate = #ToDate,
#UserId = #UserId,
#deleteflag = #deleteflag,
#RESPONSECODE = #RESPONSECODE,
#RESPONSEMESSAGE = #RESPONSEMESSAGE output,
#INVOICENO_RESPONSE = #INVOICENO_RESPONSE output
UPDATE #consumerdata1
SET responsecode = #RESPONSECODE,
responsemessage = #RESPONSEMESSAGE,
invoiceno_response = #INVOICENO_RESPONSE
WHERE customerid = #CustomerId
FETCH NEXT FROM consmr_cursor1
INTO #Id, #PrjId, #CustomerId, #UccCatId, #Area, #rate, #TotalAmt, #SubTotalAmt, #InvoiceNo, #InvoiceDate,
#DueDate, #BalanceAmt, #RoundOff, #EntryDate, #FromDate, #ToDate, #UserId, #deleteflag,
#ResponseCode, #ResponseMessage, #INVOICENO_RESPONSE
END
CLOSE consmr_cursor1
DEALLOCATE consmr_cursor1
SELECT *
FROM #consumerdata1
-- WHERE #RESPONSECODE <> 200
END
EXECUTE Bulkinvoicegeneration_lko
1,
2,
'LKO00066801'
Check this section in your procedure
DECLARE #fromDt DATETIME,
#monthdays INT = 10,
#ToDate DATETIME,
#Currentdate DATETIME,
#Year INT , ---- you need to pass some value over there
#InvoiceMonth varchar(50) = '1' --- this is passed as parameter from your procedure
SET #currentdate = CONVERT(VARCHAR, #Year) + '-'
+ CONVERT(VARCHAR, #InvoiceMonth) + '-11'
Select #currentdate ---- this value is NULL, since #Year is not passed.
Since you are using #currentdate for generating your #frmdt and #todt so they are also NULL.
DECLARE #fromDt DATETIME,
#monthdays INT = 10,
#ToDate DATETIME,
#Currentdate DATETIME,
#Year INT = 2019,
#InvoiceMonth varchar(50) = '1' --- this is passed as parameter from your procedure
SET #currentdate = CONVERT(VARCHAR, #Year) + '-'
+ CONVERT(VARCHAR, #InvoiceMonth) + '-11'
Select #currentdate ---- this value is '2019-01-11 00:00:00.000'.
---- After that
SET #fromDt = CONVERT(VARCHAR, DATEADD(d, - (DAY(DATEADD(m, -1, #currentdate - 2))), DATEADD(m, -1, #currentdate - 1)), 106)
SET #ToDate = CONVERT(DATE, Dateadd(d, -(Day(#currentdate)), #currentdate))
SET #monthdays = DATEDIFF(d, #fromDt, #ToDate) + 1
RESULT
frmdt toDate Monthdays
2018-12-01 00:00:00.000 2018-12-31 00:00:00.000 31
Update your code for setting this #currentdate once it is done hope rest of the block will fit on right place for you.... ;)
One thing I noticed is that you are not initializing the variable #year before using it.
If you want to set it to the current year, you can
SET #Year = year(getdate())
Add year parameter on this procedure.
ALTER PROCEDURE Bulkinvoicegeneration_lko #InvoiceMonth VARCHAR(20),
#PrjId BIGINT,
#CustomerId NVARCHAR(50),
#InvoiceYear INT
Then SET #Year = #InvoiceYear
Or SET YOUR #Year INT = 2019

Calculating RSI for Multiple Dates and Tickers in SQL Server 2012

I can calculate RSI for a specific end date:
DECLARE #StartingDate smalldatetime
DECLARE #EndingDate smalldatetime
DECLARE #StockID char(15)
DECLARE #DAYS INT
DECLARE #AG FLOAT
DECLARE #AL FLOAT
DECLARE #RS FLOAT
SET #StartingDate = '20180301'
SET #EndingDate = '20180403'
SET #StockID = 'ACE'
SET #DAYS = 14
SET #AG =(
SELECT SUM([px_close]-[px_open])
FROM [dbo].[daily_data]
WHERE [Ticker] = #STOCKID
AND ([Date] BETWEEN #StartingDate AND #EndingDate)
AND ([px_close]-[px_open])>0)/#DAYS
SET #AL =(
SELECT SUM([px_close]-[px_open])
FROM [dbo].[daily_data]
WHERE [Ticker] = #STOCKID
AND ([Date] BETWEEN #StartingDate AND #EndingDate)
AND ([px_close]-[px_open])<0)/#DAYS
SET #RS = #AG/ABS(#AL)
SELECT #StockID AS Ticker, #EndingDate AS Date, 100 - (100/(1+#RS)) RSI
Here's my output:
Ticker Date RSI
ACE 2018-04-03 48.7307
How can I calculate RSI for multiple dates and multiple tickers?
You don't need to set all of these to variables. You can just add the date and ticker to the group by and avoid the redundant subqueries... something like:
SELECT
[Ticker]
,[Date]
,AG = SUM(case when (isnull([px_close],0)-isnull([px_open],0))>0 then (isnull([px_close],0)-isnull([px_open],0)) end) / #days
,AL = SUM(case when (isnull([px_close],0)-isnull([px_open],0))<0 then (isnull([px_close],0)-isnull([px_open],0)) end) / #days
,RS = (SUM(case when (isnull([px_close],0)-isnull([px_open],0))>0 then (isnull([px_close],0)-isnull([px_open],0)) end) / #days) / ABS(SUM(case when (isnull([px_close],0)-isnull([px_open],0))<0 then (isnull([px_close],0)-isnull([px_open],0)) end) / #days)
,RSI = 100 - (100/(1+(SUM(case when (isnull([px_close],0)-isnull([px_open],0))>0 then (isnull([px_close],0)-isnull([px_open],0)) end) / #days) / ABS(SUM( case when (isnull([px_close],0)-isnull([px_open],0))<0 then (isnull([px_close],0)-isnull([px_open],0)) end) / #days)))
FROM
[dbo].[daily_data]
WHERE
[Ticker] = #STOCKID
AND ([Date] BETWEEN #StartingDate AND #EndingDate)
group by
[Ticker],[Date]
Remove [Ticker] = #STOCKID from the where clause to return all Tickers

count the weekend and holiday dates and sub struct it from 2 dates if it is between of it sql

I have 3 tables with columns shown below,
Holidays : HolidayId, HolidayName, HolidayDate, Comment
Entitlements:
EntitlementId, EmployeeId, LeaveTypeId, LeavePeriodId, FromDate
, UptoDate, Entitlementdays
Weekend: WeekeindId, Weekends
TODO:
create a store procedure for insertion
Before insertion it should check and count the dates in holiday and weekend table
if it is between the date which is in the startdate and enddate of entitlement table should be subtract.
in sql
Try this one as you already have weekend table and holiday table
CREATE PROCEDURE
usp_LeaveDays (#employeeid int)
as
BEGIN
DECLARE #fromdate DATE
SET #fromdate =
SELECT convert( varchar(10),fromdate,120) fromdate
FROM Entitlement
WHERE employeeid = #employeeid
DECLARE #enddate DATE
SET #enddate =
SELECT convert ( varchar(10),enddate,120) enddate
FROM entitlement
WHERE employeeid = #employeeid
DECLARE #weekendcount INT
SET #weekendcount =
SELECT Count(*)
FROM Weekend
WHERE weekends BETWEEN #fromdate AND #enddate;
DECLARE #holidayCount INT
SET #holidaycount =
SELECT Count(*)
FROM holidays
WHERE holidaydate BETWEEN #fromdate AND #enddate
DECLARE #Totaldays INT
SET #Totaldays =
SELECT DATEDIFF(day, #fromdate, #enddate)
DECLARE #Actualdays INT
SET #Actualdays = #Totaldays - (#weekendcount + isnull(#holidayCount, 0))
DECLARE #recordCount INT
SELECT #recordCount = #Actualdays
IF (#recordCount > 0)
begin
insert into -- Enter your script here
END

Setting Variables in IF statements in SQL Server 2014

Msg 134, Level 15, State 1, Line 21
The variable name '#AsOfDate' has already been declared. Variable names must be unique within a query batch or stored procedure.
I am getting this error when running a set of IF statements. Ideally I would simply need to toggle my bit to 1 for the quarter I'm interested in and then execute my code. The IF statements would set the dates I need.
I have tried this with IF and ELSE IF, but neither seems to make a difference. Any suggestions on how I can do this would be greatly appreciated. Sadly I can't simply have it pick the quarter I'm in (or the one previous) as these reports may be requested at any time.
-------------------------
-- Choose Quarter --
-------------------------
DECLARE #Q1 BIT = 0
DECLARE #Q2 BIT = 0
DECLARE #Q3 BIT = 0
DECLARE #Q4 BIT = 0
DECLARE #Annual BIT = 0
-------------------------
--Q1
IF #Q1 = '1'
BEGIN
DECLARE #AsOfDate datetime = '2016-03-31';
DECLARE #StartDate datetime = '2016-01-01'
END
--Q2
IF #Q2 = '1'
BEGIN
DECLARE #AsOfDate datetime = '2016-06-30';
DECLARE #StartDate datetime = '2016-04-01'
END
--Q3
IF #Q3 = '1'
BEGIN
DECLARE #AsOfDate datetime = '2016-09-30';
DECLARE #StartDate datetime = '2016-07-01'
END
--Q4
IF #Q4 = '1'
BEGIN
DECLARE #AsOfDate datetime = '2016-12-31';
DECLARE #StartDate datetime = '2016-10-01'
END
-- ANNUAL
IF #Annual = '1'
BEGIN
DECLARE #AsOfDate datetime = '2016-12-31';
DECLARE #StartDate datetime = '2016-01-01'
END
-- Check to ensure a time period is set
IF (#Q1 = 0 AND #Q2 = 0 AND #Q3 = 0 AND #Q4 = 0 AND #ANNUAL = 0)
BEGIN
PRINT 'NO TIME SET'
END
-- Run Code with dates
ELSE
BEGIN
EDIT:
Disregard... actually reading my error and code clearly points to my declares being an issue not the setting of the variable... Solution is to declare the variables outside of my IF statements and SET them in the statement.
I was declaring in each IF statement instead of declaring prior to all the IF statements. Below is the updated version of the code.
DECLARE #ASOfDate DATETIME
DECLARE #StartDate DATETIME
-------------------------
-- Choose Quarter --
-------------------------
DECLARE #Q1 BIT = 0
DECLARE #Q2 BIT = 0
DECLARE #Q3 BIT = 0
DECLARE #Q4 BIT = 0
DECLARE #Anual BIT = 0
-------------------------
--Q1
IF #Q1 = '1'
BEGIN
SET #AsOfDate = '2016-03-31' ; SET #StartDate = '2016-01-01'
END
--Q2
IF #Q2 = '1'
BEGIN
SET #AsOfDate = '2016-06-30' ; SET #StartDate = '2016-04-01'
END
--Q3
IF #Q3 = '1'
BEGIN
SET #AsOfDate = '2016-09-30' ; SET #StartDate = '2016-07-01'
END
--Q4
IF #Q4 = '1'
BEGIN
SET #AsOfDate = '2016-12-31' ; SET #StartDate = '2016-10-01'
END
--ANUAL
IF #Anual = '1'
BEGIN
SET #AsOfDate = '2016-12-31' ; SET #StartDate = '2016-01-01'
END
-- Check to ensure a time period is set
IF (#Q1 = 0 AND #Q2 = 0 AND #Q3 = 0 AND #Q4 = 0 AND #ANUAL = 0)
BEGIN
PRINT 'NO TIME SET'
END
-- Run Code with dates
ELSE
BEGIN
Start of Actual Program using dates shown
END

Sql datetime calculation

I have an Excel sheet and have this formula below. I would like to calculate the same formula with sql. The result will be in second.
Thank you,
declare #t1 AS datetime
declare #t2 AS datetime
declare #t3 AS datetime
declare #t4 AS datetime
set #t1 = '2011-11-04 00:00:00.000' --start date
set #t2 = '2012-01-16 18:21:55.000' --start time
set #t3 = '2011-11-10 00:00:00.000' --end date
set #t4 = '2012-01-16 12:10:00.000' --end time
Excel formula
((end date-start date-1)+(end time-(0,375)))*24*60*60
0,375 value means 9 hour
formula result will be = 443400 second
You mention that you not using Start Time in your formula?
Here it comes:
declare #t1 AS datetime
declare #t2 AS datetime
declare #t3 AS datetime
declare #t4 AS datetime
set #t1 = '2011-11-04 00:00:00.000' --start date
set #t2 = '2012-01-16 18:21:55.000' --start time
set #t3 = '2011-11-10 00:00:00.000' --end date
set #t4 = '2012-01-16 12:10:00.000' --end time
SELECT CAST((DATEDIFF(d, #t1, #t3)-1 + (CAST(#t4 AS FLOAT) - FLOOR(CAST(#t4 AS FLOAT)) - 0.375))*24*60*60 AS INT)