I have a procedure where I have calls data for each day. From this procedure I wrote another procedure to insert and update in the destination table.
We have a job which runs for every day. But now I need to run the data for past 1 year (each day).
Below are my parameters in insert update procedure - if I need to get data for 18th my parameters values are like below
,#StartDate datetime = '2020-04-18'
,#EndDate datetime = '2020-04-19'
,#SkillLevel varchar(10)='Total'
,#Region varchar(20) = 'US'
If I need to get data for 17th my parameters values are like below
,#StartDate datetime = '2020-04-17'
,#EndDate datetime = '2020-04-18'
,#SkillLevel varchar(10)='Total'
,#Region varchar(20) = 'US'
Like this to get data for last 1 year I need to run the code for 365 days which takes huge effort
Could anyone suggest how to pass dates individually for 1 year with some loop.
Try this:
DECLARE #DataSource TABLE
(
[StartDate] DATE
);
DECLARE #BegDate DATE
,#EndDate DATE;
SELECT #BegDate = '2020-01-01'
,#EndDate = '2020-12-31';
DECLARE #EndNumber BIGINT;
SELECT #EndNumber = DATEDIFF(DAY, #BegDate, #EndDate);
INSERT INTO #DataSource ([StartDate])
SELECT TOP (#EndNumber) DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY T1.[number])-1, #BegDate)
FROM master..spt_values T1
CROSS JOIN master..spt_values T2;
WHILE EXISTS(SELECT 1 FROM #DataSource)
BEGIN;
SELECT TOP 1 #BegDate = [StartDate]
,#EndDate = DATEADD(DAY, 1, [StartDate])
FROM #DataSource;
--
EXEC [stored_precedure] #StartDate = #BegDate
,#EndDate = #EndDate
,#SkillLevel ='Total'
,#Region = 'ES'
--
DELETE FROM #DataSource
WHERE [StartDate] = #BegDate;
END;
I am trying to write a query based on datetime and weekday in sql server where my output should be like :
My table descriptions are:
**Branch**(DateKey integer,
BranchName varchar2(20),
TransactionDate datetime,
OrderCount integer)
**Date**(DateKey integer PrimaryKey,
DayNameofWeek varchar2(15))
This is the raw data I have
So, this is quite a long shot but I solved it the following way:
I created a table valued function, which would take a date as a parameter and find all 15-minute intervals during that day.
For each day it would go from 00:00, to 00:15, 00:30 up to 23:30, 23:45, and 23:59. It also returns each interval start time and end time, since we will need to use this for every row in your branch table to check if they fall into that time slot and if so, count it in.
This is the function:
create function dbo.getDate15MinIntervals(#date date)
returns #intervals table (
[interval] int not null,
[dayname] varchar(20) not null,
interval_start_time datetime not null,
interval_end_time datetime not null
)
as
begin
declare #starttime time = '00:00';
declare #endtime time = '23:59';
declare #date_start datetime;
declare #date_end datetime;
declare #min datetime;
select #date_start = cast(#date as datetime) + cast(#starttime as datetime), #date_end = cast(#date as datetime) + cast(#endtime as datetime);
declare #minutes table ([date] datetime)
insert into #minutes values (#date_start), (#date_end) -- begin, end of the day
select #min = DATEADD(mi, 0, #date_start)
while #min < #date_end
begin
select #min = DATEADD(mi, 1, #min)
insert into #minutes values (#min)
end
insert into #intervals
select ([row]-1)/15+1 intervalId, [dayname], min(interval_time) interval_start_time
> -- **NOTE: This line is the only thing you need to change:**
, DATEADD(ms, 59998, max(interval_time)) interval_end_time
from
(
select row_number() over(order by [date]) as [row], [date], datename(weekday, [date]) [dayname], [date] interval_time
from #minutes
) t
group by ([row]-1)/15+1, [dayname]
order by ([row]-1)/15+1
return
end
--example of calling it:
select * from dbo.getDate15MinIntervals('2017-07-14')
Then, I am querying your branch table (you don't really need the Date table, the weekday now you have it in the function but even if not, there's a DATENAME function in SQL Server, starting with 2008 that you can use.
I would query your table like this:
select branchname, [dayname], ISNULL([11:30], 0) as [11:30], ISNULL([11:45], 0) as [11:45], ISNULL([12:00], 0) as [12:00], ISNULL([12:45], 0) as [12:45]
from
(
select intervals.[dayname]
, b.branchname
, convert(varchar(5), intervals.interval_start_time, 108) interval_start_time -- for hh:mm format
, sum(b.ordercount) ordercount
from branch b cross apply dbo.getDate15MinIntervals(CAST(b.TransactionDate as date)) as intervals
where b.transactiondate between interval_start_time and interval_end_time
group by intervals.[dayname], b.branchname, intervals.interval_start_time, intervals.interval_end_time
) t
pivot ( sum(ordercount) for interval_start_time in ( [11:30], [11:45] , [12:00], [12:45] )) as p
Please note I have used in the PIVOT function only the intervals I can see in the image you posted, but of course you could write all 15-minute intervals of the day manually - you would just need to write them once in the pivot and once in the select statement - or optionally, generate this statement dynamically.
How can I create a method to subtract two dates and this is equal to in real date as format datetime2(7) in sql server 2008.
For example ,I create this method:
Delete from TblMessage
Where MDateTime<((SELECT TOP (1)MDateTime FROM TblMessage ORDER BY MDateTime DESC)- ('2013-10-04 16:47:56.0000000'))
but it is not working .I want to result of subtract two date like this:
MDateTime1:2013-10-05 16:47:56.0000000
MDateTime2:2013-09-04 16:47:56.0000000
Result:2013-01-01 00:00:00.0000000
Result=MDateTime1-MDateTime2
How can I do this. Thanks...
Perhaps you are looking for this?
select DATEADD( day, datediff(day,GETDATE(), getdate() - 10), GETDATE() ) ;
DATEDIFF(dayofyear,MDateTime1,MDateTime2) AS Result
http://msdn.microsoft.com/en-us/library/ms189794.aspx
DECLARE
#DATE1 DATETIME = '2013-10-05 16:47:56.000',
#DATE2 DATETIME = '2013-09-04 17:37:42.000',
#DATEDIFF AS INT,
#BASEDATE DATETIME;
-- USE WHAT EVER DATE YOU WISH TO BE YOUR BASE DATE
SET #BASEDATE = '1/1/1900';
SET #DATEDIFF = DATEDIFF(SECOND, #DATE2, #DATE1);
SELECT #DATE1,#DATE2,#DATEDIFF, DATEADD(SECOND,#DATEDIFF,#BASEDATE)
Thus a scalar function could be created like this...
CREATE FUNCTION dbo.sf_GetMeasureDate
(
#EndDate DATETIME,
#StartDate DATETIME,
#BaseDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE #DATEDIFF AS INT
SET #DATEDIFF = DATEDIFF(SECOND, #StartDate, #EndDate);
Return DATEADD(SECOND,#DATEDIFF,#BASEDATE)
END
GO
Then within you regular SELECT statement you can call the function as such.
SELECT dbo.sf_GetMeasureDate('2013-10-05 16:47:56.000','2013-09-04 17:37:42.000','1/1/1900')
or within an existing query:
SELECT dbo.sf_GetMeasureDate([fld1],[fld2],'1/1/1900')
This is more of a syntax question
I'm trying to write a store procedure or function that I can embed into a query such as:
select * from MyBigProcOrFunction
I'm trying to define a tabular function but I do not understand how to do it as I build tmp tables to work out the data before I finally have the return at the endtable. My mark up for my code is:
create function FnGetCompanyIdWithCategories()
returns table
as
return
(
select * into a #tempTable from stuff
'
etc
'
select companyid,Company_MarketSector from #tempTables 'the returning table data
)
If I define a function, How do I return it as a table?
You can't access Temporary Tables from within a SQL Function. You will need to use table variables so essentially:
ALTER FUNCTION FnGetCompanyIdWithCategories()
RETURNS #rtnTable TABLE
(
-- columns returned by the function
ID UNIQUEIDENTIFIER NOT NULL,
Name nvarchar(255) NOT NULL
)
AS
BEGIN
DECLARE #TempTable table (id uniqueidentifier, name nvarchar(255)....)
insert into #myTable
select from your stuff
--This select returns data
insert into #rtnTable
SELECT ID, name FROM #mytable
return
END
Edit
Based on comments to this question here is my recommendation. You want to join the results of either a procedure or table-valued function in another query. I will show you how you can do it then you pick the one you prefer. I am going to be using sample code from one of my schemas, but you should be able to adapt it. Both are viable solutions first with a stored procedure.
declare #table as table (id int, name nvarchar(50),templateid int,account nvarchar(50))
insert into #table
execute industry_getall
select *
from #table
inner join [user]
on account=[user].loginname
In this case, you have to declare a temporary table or table variable to store the results of the procedure. Now Let's look at how you would do this if you were using a UDF
select *
from fn_Industry_GetAll()
inner join [user]
on account=[user].loginname
As you can see the UDF is a lot more concise easier to read, and probably performs a little bit better since you're not using the secondary temporary table (performance is a complete guess on my part).
If you're going to be reusing your function/procedure in lots of other places, I think the UDF is your best choice. The only catch is you will have to stop using #Temp tables and use table variables. Unless you're indexing your temp table, there should be no issue, and you will be using the tempDb less since table variables are kept in memory.
Use this as a template
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION <Table_Function_Name, sysname, FunctionName>
(
-- Add the parameters for the function here
<#param1, sysname, #p1> <data_type_for_param1, , int>,
<#param2, sysname, #p2> <data_type_for_param2, , char>
)
RETURNS
<#Table_Variable_Name, sysname, #Table_Var> TABLE
(
-- Add the column definitions for the TABLE variable here
<Column_1, sysname, c1> <Data_Type_For_Column1, , int>,
<Column_2, sysname, c2> <Data_Type_For_Column2, , int>
)
AS
BEGIN
-- Fill the table variable with the rows for your result set
RETURN
END
GO
That will define your function. Then you would just use it as any other table:
Select * from MyFunction(Param1, Param2, etc.)
You need a special type of function known as a table valued function. Below is a somewhat long-winded example that builds a date dimension for a data warehouse. Note the returns clause that defines a table structure. You can insert anything into the table variable (#DateHierarchy in this case) that you want, including building a temporary table and copying the contents into it.
if object_id ('ods.uf_DateHierarchy') is not null
drop function ods.uf_DateHierarchy
go
create function ods.uf_DateHierarchy (
#DateFrom datetime
,#DateTo datetime
) returns #DateHierarchy table (
DateKey datetime
,DisplayDate varchar (20)
,SemanticDate datetime
,MonthKey int
,DisplayMonth varchar (10)
,FirstDayOfMonth datetime
,QuarterKey int
,DisplayQuarter varchar (10)
,FirstDayOfQuarter datetime
,YearKey int
,DisplayYear varchar (10)
,FirstDayOfYear datetime
) as begin
declare #year int
,#quarter int
,#month int
,#day int
,#m1ofqtr int
,#DisplayDate varchar (20)
,#DisplayQuarter varchar (10)
,#DisplayMonth varchar (10)
,#DisplayYear varchar (10)
,#today datetime
,#MonthKey int
,#QuarterKey int
,#YearKey int
,#SemanticDate datetime
,#FirstOfMonth datetime
,#FirstOfQuarter datetime
,#FirstOfYear datetime
,#MStr varchar (2)
,#QStr varchar (2)
,#Ystr varchar (4)
,#DStr varchar (2)
,#DateStr varchar (10)
-- === Previous ===================================================
-- Special placeholder date of 1/1/1800 used to denote 'previous'
-- so that naive date calculations sort and compare in a sensible
-- order.
--
insert #DateHierarchy (
DateKey
,DisplayDate
,SemanticDate
,MonthKey
,DisplayMonth
,FirstDayOfMonth
,QuarterKey
,DisplayQuarter
,FirstDayOfQuarter
,YearKey
,DisplayYear
,FirstDayOfYear
) values (
'1800-01-01'
,'Previous'
,'1800-01-01'
,180001
,'Prev'
,'1800-01-01'
,18001
,'Prev'
,'1800-01-01'
,1800
,'Prev'
,'1800-01-01'
)
-- === Calendar Dates =============================================
-- These are generated from the date range specified in the input
-- parameters.
--
set #today = #Datefrom
while #today <= #DateTo begin
set #year = datepart (yyyy, #today)
set #month = datepart (mm, #today)
set #day = datepart (dd, #today)
set #quarter = case when #month in (1,2,3) then 1
when #month in (4,5,6) then 2
when #month in (7,8,9) then 3
when #month in (10,11,12) then 4
end
set #m1ofqtr = #quarter * 3 - 2
set #DisplayDate = left (convert (varchar, #today, 113), 11)
set #SemanticDate = #today
set #MonthKey = #year * 100 + #month
set #DisplayMonth = substring (convert (varchar, #today, 113), 4, 8)
set #Mstr = right ('0' + convert (varchar, #month), 2)
set #Dstr = right ('0' + convert (varchar, #day), 2)
set #Ystr = convert (varchar, #year)
set #DateStr = #Ystr + '-' + #Mstr + '-01'
set #FirstOfMonth = convert (datetime, #DateStr, 120)
set #QuarterKey = #year * 10 + #quarter
set #DisplayQuarter = 'Q' + convert (varchar, #quarter) + ' ' +
convert (varchar, #year)
set #QStr = right ('0' + convert (varchar, #m1ofqtr), 2)
set #DateStr = #Ystr + '-' + #Qstr + '-01'
set #FirstOfQuarter = convert (datetime, #DateStr, 120)
set #YearKey = #year
set #DisplayYear = convert (varchar, #year)
set #DateStr = #Ystr + '-01-01'
set #FirstOfYear = convert (datetime, #DateStr)
insert #DateHierarchy (
DateKey
,DisplayDate
,SemanticDate
,MonthKey
,DisplayMonth
,FirstDayOfMonth
,QuarterKey
,DisplayQuarter
,FirstDayOfQuarter
,YearKey
,DisplayYear
,FirstDayOfYear
) values (
#today
,#DisplayDate
,#SemanticDate
,#Monthkey
,#DisplayMonth
,#FirstOfMonth
,#QuarterKey
,#DisplayQuarter
,#FirstOfQuarter
,#YearKey
,#DisplayYear
,#FirstOfYear
)
set #today = dateadd (dd, 1, #today)
end
-- === Specials ===================================================
-- 'Ongoing', 'Error' and 'Not Recorded' set two years apart to
-- avoid accidental collisions on 'Next Year' calculations.
--
insert #DateHierarchy (
DateKey
,DisplayDate
,SemanticDate
,MonthKey
,DisplayMonth
,FirstDayOfMonth
,QuarterKey
,DisplayQuarter
,FirstDayOfQuarter
,YearKey
,DisplayYear
,FirstDayOfYear
) values (
'9000-01-01'
,'Ongoing'
,'9000-01-01'
,900001
,'Ong.'
,'9000-01-01'
,90001
,'Ong.'
,'9000-01-01'
,9000
,'Ong.'
,'9000-01-01'
)
insert #DateHierarchy (
DateKey
,DisplayDate
,SemanticDate
,MonthKey
,DisplayMonth
,FirstDayOfMonth
,QuarterKey
,DisplayQuarter
,FirstDayOfQuarter
,YearKey
,DisplayYear
,FirstDayOfYear
) values (
'9100-01-01'
,'Error'
,null
,910001
,'Error'
,null
,91001
,'Error'
,null
,9100
,'Err'
,null
)
insert #DateHierarchy (
DateKey
,DisplayDate
,SemanticDate
,MonthKey
,DisplayMonth
,FirstDayOfMonth
,QuarterKey
,DisplayQuarter
,FirstDayOfQuarter
,YearKey
,DisplayYear
,FirstDayOfYear
) values (
'9200-01-01'
,'Not Recorded'
,null
,920001
,'N/R'
,null
,92001
,'N/R'
,null
,9200
,'N/R'
,null
)
return
end
go
You don't need (shouldn't use) a function as far as I can tell. The stored procedure will return tabular data from any SELECT statements you include that return tabular data.
A stored proc does not use RETURN statements.
CREATE PROCEDURE name
AS
SELECT stuff INTO #temptbl1
.......
SELECT columns FROM #temptbln