multiple where clause dates - sql

I pass two date range to my procedure then I select last date of each and every month as below
create procedure stcheck
#From_Date date,
#To_Date date
as
begin
declare #tmpTable table (dates date)
declare #startDate date = #From_Date
declare #endDate date = #To_Date
while #startDate <= #endDate
begin
insert into #tmpTable (dates) values (#startDate)
set #startDate = DATEADD(DAY, 1, #startDate)
end
select max(dates) as [Last day] from #tmpTable as o
group by datepart(YEAR, dates), datepart(MONTH, dates)
If am getting result as follows
Last day
2017-01-31
2017-02-28
2017-03-31
2017-04-30
I need to pass some data to temporary table by using these date output
Ex :-
Insert #xyz
Select * from abcd where postdate <=’2017-01-31’
And my requirement is that these all dates should be automatically used and relevant data should pass to #table.
Hi expert . thank for your early reply.
In brief my requirement is as follows. Please help because I am new with sql.
Think,I have a table as ‘stock’ with in and out stock transaction and stock
report can be taken as follows to any as at date
SELECT item ,SUM(InQty-OutQty) FROM stock
WHERE TransDate <= #AsatDate
GROUP BY item
Having SUM(InQty-OutQty) > 0
If I need to get the each and every month end stock when I am passing the date range
from #From date= ‘2017/05/01’ to #AsatDate=‘2017/09/30’ .
The stock report result should be appear something like this.
STOCK REPORT EXAMPLE
Please help what can be done?
NB:- it should be able to pass any date range when it is required.

Your question is a little unclear, but I'm assuming you want to run the stored procedure and insert data into the temp table #xyz (assumes temp table #xyz already exists):
insert into #xyz
exec stcheck #From_Date, #To_Date
Now off on a little tangent:
I'd also look at table-valued functions if you need parameterized, deterministic tabular output like this. I agree with #John that you should avoid looping if possible. One possible way to achieve this is instead of iterating day by day you use a pre-populated calendar table (stick say 50-100 years worth of future calendar dates in a table and use this in calculations - there are tons of examples of how to do this online). Another method is to use a recursive CTE or a numbers table, both outlined in answers here.
Once your calendar dates are easily queryable, you can stick all this in a view or inline table-valued function and it will be super fast and much clearer. If you regularly use "last day of month" as a filter criteria, you could even pre-calculate these as a column in your calendar table. Here's what it could end up like:
insert into #xyz
select dbo.DatesBetween(#From_Date, #To_Date)
You could even use dbo.DatesBetween(#From_Date, #To_Date) directly in your query in place of the temp table, if it's only used once.

Related

SQL Server DATETIME, automatically fill at exactly 10pm of the day when not fill before 10pm of the same day

Table structure:
ID int
status varchar (10)
DATE_CREATED datetime
DATE_CLOSED datetime
Stored procedure for filling DATE_CREATED:
CREATE PROCEDURE [dbo].[...]
#ID INT,
#STATUS VARCHAR(10) = 'Open',
#DATE_CREATED DATETIME = NULL
AS
SET NOCOUNT ON
UPDATE table
SET STATUS = #STATUS,
DATE_CREATED = COALESCE(#DATE_CREATED, GETDATE())
FROM table
From that point the column DATE_CLOSED is NULL. I wanted to automatically fill the column with the date of DATE_CREATED column but with the time of 10pm, and it should be filled by 10pm automatically and also the status filled to 'closed'.
You can calculate 10 p.m. on the current date using:
dateadd(hour, 22, cast(cast(getdate() as date) as datetime))
This is easy to add into the update. I'm not 100% sure, though, that this is all you are asking for.
If you are looking to schedule a query or stored procedure to run at a set time of the day, then the normal approach is to use SQL Server Agent which has fairly elaborate job scheduling functionality.
Look at this question for an example of how to run a daily job.
how to schedule a job for sql query to run daily?
And here's Microsoft's documentation: https://learn.microsoft.com/en-us/sql/ssms/agent/schedule-a-job

Iterative Union ALL's

I have a large SQL Server 2012 Database which I am querying 3 tables to create a result set of 5 fields.
I want to repeat this query in a WHILE - loop and "UNION ALL" the result sets obtained in each loop. This iteration will be on a variable: #this_date which will increment over the past 6 years and stop at today's date.
At each iteration a different results set will be obtained by the SELECT.
So I am trying to code the Stored Procedure as follows:
Declare #the_date as Date,
#to_date as Date
-- I setup the above dates, #the_date being 6 years behind #to_date
-- Want to loop for each day over the 6-year period
WHILE (#the_date <= #to_date)
BEGIN
-- the basic select query looks like this
Select Table1.Field-1, Table2.Field-2 ...
FROM Table1
Inner Join Table2 ...
On ( ..etc.. )
-- the JOIN conditions are based on table.attributes which are compared with
-- #the_date to get a different result set each time
-- now move the date up by 1
DateAdd(Day, +1, #the_date)
-- want to concatenate the result sets
UNION ALL
END
The above gives me a syntax error:
Incorrect syntax near the keyword 'Union'.
Any ideas on a solution to my problem would be welcome
- thanks.
Don't use a UNION. You can't in a loop anyway. Instead store the results of each iteration in a temp table or a table variable and select from the temp table / table variable instead.
DECLARE #the_date as Date,
#to_date as Date
CREATE TABLE #t (Col1 VARCHAR(100))
WHILE (#the_date <= #to_date)
BEGIN
INSERT #t (Col1) SELECT ... etc
DateAdd(Day, +1, #the_date)
END
SELECT Col1 FROM #t
That said, if you provide some sample data and expected results we might be able to help you with a more efficient set-based solution. You should avoid iterative looping in RDBMS whenever possible.

Query to Stored Procedure in SSRS

I am getting data from a table and I am writing off to the report through a stored procedure. In the reporting part it has to show the results by users defined date.
E.g:
Today - should show today's results only
Yesterday - should show Yesterday's results only
How should I declare the values in a stored procedure and how can I implement in ssrs reporting part?
My CreateDate column keeps changing has the table (FailedJobsInfo) gets updated.
Here is my stored procedure:
ALTER PROCEDURE [dbo].[FailedJobsInfo]
#StartDate DATETIME
AS
SELECT
[SQLServer]
,[JobName]
,[StepName]
,[FailureMessage]
,[RunDateTime]
,[RunDuration]
,[CreateDate]
FROM
[dbo].[FailedJobsInfo]
WHERE
CONVERT(varchar(20), CreateDate, 101) = CONVERT(varchar(20), GETDATE(), 101)
Starting from your SSRS Report.
1) Create a Parameter with Labels and Values as below
Label Value
Today 0
Yesterday 1
2) Make your Procedure to accept an INT Parameter, If user selects Today it will pass zero 0 to stored procedure, if user selects Yesterday it will pass procedure 1 to procedure and this Integer value will be subtracted from your getdate() value avoiding time part. you will need to do as follow :
ALTER PROCEDURE [dbo].[FailedJobsInfo]
#StartPeriod INT
AS
BEGIN
SET NOCOUNT ON;
SELECT
[SQLServer]
,[JobName]
,[StepName]
,[FailureMessage]
,[RunDateTime]
,[RunDuration]
,[CreateDate]
FROM
[dbo].[FailedJobsInfo]
WHERE
CAST(CreateDate AS DATE) = CAST(GETDATE() AS DATE) - #StartPeriod --<--
END

Avoiding while loops in SQL when a counter is required

I feel like this is a common problem, but it seems that none of the answers that I have found on SO or other sites seem to address the issue of a while loop with a counter.
Let's say that I am trying to write a stored procedure in SQL that will populate a user's timesheet by inserting a row for each day for the remainder of the month. If the #endMonth variable holds the last day of the month, then I know that I could easily write a while loop and do something along these lines:
WHILE #date <= #endMonth
BEGIN
//Do some action with the date, like an insert
SET #date = DATEADD(d, 1, #date) //increment the date by one day
END
However, looking at answers here and on other sites leads me to believe that it would be best to avoid using a while loop if at all possible.
So my question is this: is there a way I can implement a loop with a counter in SQL without using the WHILE structure? What technique would I use to go about converting a loop similar to the one I posted? Or with something like this, do I have to bite the bullet and just use a while loop?
As an aside, some of the following questions come close, but none of them seem to quite address the issue of needing a counter as a loop condition. Most of the answers seem to condemn using WHILE loops, but I can't seem to find a general purpose solution as to an alternative.
sql while loop with date counter
SQL Server 2008 Insert with WHILE LOOP (this one was close, but unfortunately for me it only works with an auto increment column)
I saw many examples of populating data.
First you create dates from starting to ending dates in cte and then you can insert it into table.
One of them is with cte:
DECLARE #StartDate DateTime = '2014-06-01'
DECLARE #EndDate DateTime = '2014-06-29'
;WITH populateDates (dates) AS (
SELECT #StartDate as dates
UNION ALL
SELECT DATEADD(d, 1, dates)
FROM populateDates
WHERE DATEADD(d, 1, dates)<=#EndDate
)
SELECT *
INTO dbo.SomeTable
FROM populateDates
You should try to look for on internet how to populate date in sql table
As a general case, you can increment values without using cursors by assigning values and incrementing the variable in the same select, like this:
DECLARE #i INT = 0
DECLARE #table TABLE
(
ID INT ,
testfield VARCHAR(5)
)
INSERT INTO #table
( testfield )
VALUES ( 'abcd'),
( 'efgh' ),
( 'ijkl' ),
( 'mnop' )
UPDATE #table
SET #I = ID = #i + 1
SELECT *
FROM #table
I used a sequence - create temporarily.
I needed to do my updates outside of script context, with plain SQL, sequence was the only "counter" I could come up with.

SQL Server 2000 (creating all dates given a daterange)

I was wondering if there is a way in SQL Server 2000 to create all dates given a start and end date as a result. I know I can achieve this with T-SQL looping. I am looking for a non looping solution. Also in 2005 you can use the recursive with clause. The solution can also be using a T table that has numbers in it to join with the table. Again I am looking at a SQL Server 2000 non looping/using T tables solution. Is there any?
SELECT
DATEADD(dy, T.number, #start_date)
FROM
T
WHERE
number BETWEEN 0 AND DATEDIFF(dy, #start_date, #end_date)
A Calendar table can also be useful for these kind of queries and you can add some date-specific information to it, such as whether a day is a holiday, counts as a "business" day, etc.
try this:
create numbers table, only need to do this one time in your DB:
CREATE TABLE Numbers (Number int NOT NULL)
GO
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
GO
DECLARE #x int
set #x=0
WHILE #X<8000
BEGIN
SET #X=#X+1
INSERT INTO Numbers VALUES (#x)
END
--run your query:
DECLARE #StartDate datetime
DECLARE #EndDate datetime
set #StartDate='05/03/2009'
set #EndDate='05/12/2009'
SELECT
#StartDate+Number-1
FROM Numbers
WHERE Number<=DATEDIFF(day, #StartDate, #EndDate)+1