ALTER PROCEDURE [dbo].[spGetData]
#startdate DATE
AS
WITH dates(Date) AS
(
SELECT #startdate AS Date
UNION ALL
SELECT DATEADD (d, 1, [Date])
FROM dates
WHERE DATE < GETDATE()
)
SELECT Date
FROM dates
OPTION (MAXRECURSION 0)
GO
it returns a list of dates
exec spGetData #startdate = '2019/11/28'
Output:
Date
----------
2019-11-28
2019-11-29
2019-11-30
2019-12-01
2019-12-02
2019-12-03
How do I select each date individually in the same stored procedure as I want to pass date as parameter in another stored procedure?
All you need to do is ditch all the current code and put a WHILE loop that starts with the current date and increments it with DATEADD each time.
I'm presuming you have a reason that the other SP needs to be called separately for each date.
First define a table type like :
CREATE TYPE UT_Date AS TABLE
(
startdate date
)
You can use this to pass multiple records in Stored procedure as parameter like:
CREATE PROCEDURE USP_OtherSP(#Dates [UT_Date])
AS
BEGIN
--you can access table valued parameter data just like a table
SELECT * FROM #Dates
-- your logic here
END
Related
I'm trying to create a procedure that the user inputs a month in the Textbox and presses the button, the user is presented with the data of average price per night for for all the cities in the vacations database.
For Example:
Amsterdam: 134.44
and when the startdate is in the same month as the input and the enddate is not to calculate only th days in the month that the user inputs and vise versa for the enddate
this is mt procedure :
ALTER PROCEDURE sp_AdminAvgPriceMonth
-- Add the parameters for the stored procedure here
#month int
AS
BEGIN
-- Insert statements for procedure here
select case
when month(StartDate)= #month and month(EndDate)=#month
then avg(datediff(day, StartDate, EndDate)*price)
when month(StartDate)=#month and month(EndDate)<>#month
then avg(datediff(day, StartDate, EOMONTH(StartDate))*price)
--month(StartDate)<>#month and month(EndDate)=#month
else avg(datediff(day, DATEADD(month, DATEDIFF(month, 0, StartDate), 0), EndDate)*price)
end as avrgPrice
from VacationsTable VT inner join FlatsTable FT on VT.FlatId=FT.FlatId
group by City
I haven't checked your logic, but you will likely need to move your CASE statements inside your AVG() statements... It is like the error message explains, that StartDate is not inside your aggregates. Try structuring like below
select avg( case
when month(StartDate)= #month and month(EndDate)=#month
then (datediff(day, StartDate, EndDate)*price) --etc
And then check your logic if you get no further errors.
Sometimes, I find it is helpful to use a subquery, CTE, or temporary table result to separate your business formula logic from your report aggregation logic. So consider that, as well if it helps.
I have 2 dates column, one is current date and the one is user define date, I have to display the specific row when the user define date is 2days greater than current date.
In the below code I try to display the row, when both dates are equal. But I don't know how display the row in sql.
I have following Columns,
Rid
DateTime (User define date and time)
Reminder
Description
CRDateTime (current date and time)
I have to set 3 condition.
if both dates are equal means that should be display,
if DateTime is 2 days before CRDate means I have to display that row,
if DateTime is 1 day before the CRdate means I have to display that row.
declare DateTime as datetime1;
select RId if CAST (DateTime as date) =CAST (#CRDateTime as date)
The IF...ELSE statement is a control-flow statement that allows you to execute or skip a statement block based on a specified condition.
For example:
IF Boolean_expression
BEGIN
-- Statement block executes when the Boolean expression is TRUE
END
ELSE
BEGIN
-- Statement block executes when the Boolean expression is FALSE
END
If you want to check something in your SQL Statements you should use the where clause.
It could be looking like:
SELECT * FROM `[YOUR_TABLE_NAME]` WHERE `DateTime` = `CRDateTime`
If you want to check the date in a 2 Day decade you can use the SQL DATEADD Function.
It lookse like:
SELECT DATEADD(day, +1, '2017/08/25') AS DateAdd;
Resault of this code is 2017/08/26
In your case it looks like this:
SELECT RId where DATEADD(day, +2, DateTime) = CRDateTime
--- EDIT SECTION: ---
EDIT 1:
All in one you can use this code here:
SELECT RId WHERE
`DateTime` = `CRDateTime` OR
DATEADD(day, +1, DateTime) = CRDateTime OR
DATEADD(day, +2, DateTime) = CRDateTime
As I understand you basically want to show all the records with in range of 2 days.
SELECT RId, DateTime, Reminder, Description, CRDateTime
WHERE CRDateTime BETWEEN DATETIME AND DATEADD(day, +2, DateTime)
Or you may try this
SELECT RId, DateTime, Reminder, Description, CRDateTime
WHERE DateTime BETWEEN DATEADD(day, -2, CRDateTime) AND CRDateTime
The question isn't clear. I assume the actual question is how to filter a table's rows between two dates.
Filtering in SQL (in any product) is the job of the WHERE clause, not IF. You can use the BETWEEN clause to select values in a range.
If both the table field and the query parameter are date variables, the query is easy :
CREATE TABLE table1
(
RId int PRIMARY KEY,
DateField date,
INDEX IX_Table1_Date (DateField)
)
declare #dateParam date='20190801';
SELECT RId
FROM table1
WHERE DateField BETWEEN dateadd(day,-2,#dateParam) AND #DateParam
This query will take advantage of the IX_Table1_Date index to speed up the search. Typically, applying any kind of function on a table field prevents the query engine from using any index that includes that field simply because the values stored in the index have no relation to the function's result.
If you use the date parameter to be the current date, just assign GETDATE() to it.
declare #dateParam date=GETDATE();
If the field isn't a date, you can cast it to date and still get a fast range query, because the query engine is fast enough to convert the cast to a range query.
SELECT RId
FROM table1
WHERE cast(DateField as date) BETWEEN dateadd(day,-2,#dateParam) AND #DateParam
If DateField is not a date-related type, eg it's a varchar, a) that's a serious bug and b) the server won't be able to use any indexes.
Casting the parameter values won't affect performance as they actual values are calculated before the query starts executing. The query becomes quite noisy though :
declare #dateParam datetime='20190801'
SELECT RId
FROM table1
WHERE cast(DateField as date)
BETWEEN dateadd(day,-2,cast(#dateParam as date)) AND cast(#DateParam as date)
That's why it's better to use the correct type for parameters
I am trying to grant and revoke server roles for user id picked from a table.
I am using the following query to insert a row from master table to another table whenever the expiry date approaches, however the command is not inserting any rows into the slave table.
Insert into tbl2(userid, role, startdate, expirydate)
Select userid, role, startdate, expirydate
from tbl1
where expirydate = Dateadd(day,0, getdate())
If I use <= or >= the above query is working but that is not helpful when we have multiple rows in tbl1.
It's because GETDATE() returns a DATETIME value, and you're likely comparing it to a DATE, so you're effectively comparing values like this:
SELECT GETDATE() AS DateTimeValue,
CAST(GETDATE() AS DATE) DateValue;
Output:
DateTimeValue DateValue
2017-10-04 10:34:35.023 2017-10-04
By default, a DATE will have a time set to midnight if comparing to a DATETIME, like: 2017-10-04 00:00:00.000.
These values aren't going to be equal with a time included, so use CAST or CONVERT to get a DATE without the time:
where expirydate = Dateadd(day,0, CAST(GETDATE() AS DATE))
Although, it looks like you don't need that Dateadd on the WHERE clause, so remove it unless this is edited / sample code. So maybe edit it to this:
where expirydate = CAST(GETDATE() AS DATE)
Reference
GETDATE (Transact-SQL)
Returns the current database system timestamp as a datetime value without the database time zone offset. This value is derived from the operating system of the computer on which the instance of SQL Server is running.
I am having some issues with getting dates showing up in my query when I changed the dates in my variable, below is what I have declared.
declare #record int;
declare #start_date date;
declare #end_date date;
set #record = 2;
set #start_date = '2016-03-01';
set #end_date = '2016-03-31';
What I have created is temp tables which populate my data by Date ranges. The dates are set up as below
- Daily 2016-01-15
- weekly 2016-51
- Monthly 2016-04
- Quarterly 2016-01
- Yearly 2016
So when I declare the dates above and filter by yearly I should get data back, in fact no matter what date I put in for yearly I should get results but nothing is showing up.
When I declare the start date = 2016-01-01 it returns data for everything I filter by.
Can anybody offer some advice on a way to fix this problem I have no idea.
I don't know what is your query which is not working, but the basic isead sould be like that:
select * from YourTempTable where datepart (yy, DateField) = datepart(yy, #start_date)
of course this is not optimal for big tables as it wouldn't use any index.
Better would be to construct a #DateFrom and #DateTo variables based on the period you are looking for and the reference dates described above and make your select accordingly:
select * from YourTempTable where DateField between = #DateFrom and #DateTo
I have a table which has list of some events with dates. I am trying to write a stored procedure that will return only the upcoming events.
I have written the following query in the stored procedure:
SELECT *
FROM Events
WHERE tDate >= (select CAST(GETDATE() as DATE))
But this is not returning correct result. This is also showing results that have dates less than current date. How to write a query that will return all the events that have date equal or greater than today's date.
Edit: Dates that have been entered on the table have the format yyyy/dd/mm and getdate() returns date in the format yyyy/mm/dd. I think this is causing the problem. Dates that have been entered into the table has been taken using jquery date picker. Any solution to this problem?
Not sure why you have an additional select
SELECT *
FROM Events
WHERE tDate >= CAST(GETDATE() as DATE)
your DATE data is incorrectly stored within Sql Server. When your application passes the string '2015-09-04' and you save that your date column, it is saved as 4th Sept 2015 and not 9th April 2015. Hence your query returns such rows as they are greater than GETDATE().
Example
DECLARE #D VARCHAR(10) = '2015-09-04'
SELECT CONVERT(VARCHAR(20),CONVERT(DATE,#D),109)
you need to fix your data and then use a CONVERT with style when saving dates in your table from application, using something like this. CONVERT(DATE, '20150409',112)
DECLARE #D VARCHAR(10) = '20150409'
SELECT CONVERT(VARCHAR(20),CONVERT(DATE,#D,112),109)
Refer these threads for more info:
Impossible to store certain datetime formats in SQL Server
Cast and Convert