Dynamic statement for Yesterday in Microsoft SQL Server Management Studio - sql-server-2008-r2

I run the below query to check if something ran the previous day. The below query works, but I have to change the date each day to get the results I want. I've tried multiple things that I've found that seem like they should return results, but they don't quite seem to work.
select * from Linking_Results
where Evaluated between '2015-02-04 00:00:01.001' and '2015-02-04 23:59:00.999'
and Linked = '1' order by Evaluated
So my question is, how do I make a dynamic statement for yesterday and keep from having to change the date daily?

You can use the dateadd and getdate functions.
declare #start datetime,
#end datetime
-- subtract one day and cast it as a date to drop the time portion
select #start = cast(dateadd(day, -1, getdate()) as date)
-- add one day and subtract 3ms to get the end of yesterday (apparently SQL rounds)
select #end = dateadd(ms, -3, dateadd(day, 1, #start))
The values would then be
2015-02-04 00:00:00.000
2015-02-04 23:59:59.997
and you can do a between on these two variables. Since you use between which is inclusive, you need to account for the time portion. You could change the where clause to go to the next day and do an exclusive check on #end
select #end = dateadd(day, 1, #start)
where Evaluated >= #start and Evaluated < #end

Related

I got one problem in SQL,i need to get start of next minute value

I need to get the start of next Minute value, that means suppose I got the output for GETDATE() is 19.11.2019 12:52:51 but I need to get 19.11.2019 12:53:00
This is my code:
DECLARE #date DATETIME
SET #date = GETDATE()
DECLARE #increase int = 1;
SELECT DATEADD(mi, #increase,#date) as nextminutedate;
You want to round the date down. One method in SQL Server is:
select dateadd(minute, 1+datediff(minute, 0, getdate()), 0)
This is a little inscrutable. The datediff() calculates the number of minutes from a time of 0 for the current date/time. The dateadd() adds this back in.
Note: This works for minutes. You might have overflow problems with seconds or milliseconds.
For this reason, I rather prefer:
select dateadd(minute, 1+datediff(minute, '2000-01-01', getdate()), '2000-01-01')
I find this is clearer in the intention.

T-sql IF Condition date evaluation

I have a simple question regarding T-SQL. I have a stored procedure which calls a Function which returns a date. I want to use an IF condition to compare todays date with the Functions returned date. IF true to return data.
Any ideas on the best way to handle this. I am learning t-sql at the moment and I am more familar with logical conditions from using C#.
ALTER FUNCTION [dbo].[monday_new_period](#p_date as datetime) -- Parameter to find current date
RETURNS datetime
BEGIN
-- 1 find the year and period given the current date
-- create parameters to store period and year of given date
declare #p_date_period int, #p_date_period_year int
-- assign the values to the period and year parameters
select
#p_date_period=period,
#p_date_period_year = [year]
from client_week_uk where #p_date between start_dt and end_dt
-- 2 determine the first monday given the period and year, by adding days to the first day of the period
-- this only works on the assumption a period lasts a least one week
-- create parameter to store the first day of the period
declare #p_start_date_for_period_x datetime
select #p_start_date_for_period_x = min(start_dt)
from client_week_uk where period = #p_date_period and [year] = #p_date_period_year
-- create parameter to store result
declare #p_result datetime
-- add x days to the first day to get a monday
select #p_result = dateadd(d,
case datename(dw, #p_start_date_for_period_x)
when 'Monday' then 0
when 'Tuesday' then 6
when 'Wednesday' then 5
when 'Thursday' then 4
when 'Friday' then 3
when 'Saturday' then 2
when 'Sunday' then 1 end,
#p_start_date_for_period_x)
Return #p_result
END
ALTER PROCEDURE [dbo].[usp_data_to_retrieve]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF monday_new_period(dbo.trimdate(getutcdate()) = getutcdate()
BEGIN
-- SQL GOES HERE --
END
Thanks!!
I assume you are working on Sql2008. See documentation of IF and CASE keywords for more details.
CREATE FUNCTION dbo.GetSomeDate()
RETURNS datetime
AS
BEGIN
RETURN '2012-03-05 13:12:14'
END
GO
IF CAST(GETDATE() AS DATE) = CAST(dbo.GetSomeDate() AS DATE)
BEGIN
PRINT 'The same date'
END
ELSE
BEGIN
PRINT 'Different dates'
END
-- in the select query
SELECT CASE WHEN CAST(GETDATE() AS DATE) = CAST(dbo.GetSomeDate() AS DATE) THEN 1 ELSE 0 END AS IsTheSame
This is the basic syntax for a T-SQL IF and a date compare.
If you are comparing just the date portion for equality you will need to use:
select dateadd(dd,0, datediff(dd,0, getDate()))
This snippet will effectively set the time portion to 00:00:00 so you can compare just dates. So in use it will look something like this.
IF dateadd(dd,0, datediff(dd,0, fn_yourFunction())) = dateadd(dd,0, datediff(dd,0, GETDATE()))
BEGIN
RETURN SELECT * FROM SOMEDATA
END
Hope that helps!

Count differnce of two Date's with Respect that every month has EXACT 30 days

I thought it was clear, but doesn't seem so.
This question is about T-SQL (since it's tagged with tsql :) )
So I couldn't find any out-of-the-box solution to calculate my problem.
Let's assume you have these two dateTimes:
DECLARE #start DATETIME = '2011-01-01',
#end DATETIME = '2011-04-15'
The difference of these two datetimes in Days should be quivalent to 105.
The calculation works as follows: For every full month add 30 days, for the rest add the days till the date is achieved.
I could program this, but it would be an enormous SQL-statement, which I find find kinda ugly.
Is there any simple solution for this, like a built-in function or something short?
Thanks in advance.
Does this do the trick?
;with dates as
(
SELECT
CAST ('2011-01-01' AS DATETIME) as start_date
,CAST('2011-04-15' AS DATETIME) as end_date
)
SELECT
start_date
,end_date
,CASE WHEN DATEDIFF(MM,start_date,end_date) = 0 THEN DAY(end_date) - DAY(start_date)
WHEN DAY(start_date) = 1 THEN (30 * (DATEDIFF(MM,start_date,end_date))) + DAY(end_date)
WHEN DAY(start_date) <> 1 THEN 30 * DATEDIFF(MM,start_date,end_date) + (DAY(end_date) - DAY(start_date))
END AS gap_in_days
FROM dates
Short Answer
There's no built in function, but you could pretty easily create your own to handle converting a datetime to an int. From there, the SQL you would have to write would be trivial.
Long Answer
There's no built in function that will do this, probably because every month doesn't have 30 days. :)
You can start with this:
DECLARE #start DATETIME = '2011-01-01',
#end DATETIME = '2011-04-15'
DECLARE #endConverted INT
SELECT #endConverted = DATEPART(month, #end) * 30
+ CASE
WHEN DATEPART(DAY, #end) <= 30
THEN datepart(DAY, #end)
ELSE 30
END
DECLARE #startConverted INT
SELECT #startConverted = DATEPART(MONTH, #start) * 30
+ CASE
WHEN DATEPART(DAY, #start) <= 30
THEN DATEPART(DAY, #start)
ELSE 30
END
SELECT #endConverted - #startConverted
This isn't beautiful SQL, but it works. Note that it returns 104 (because 15 days - 1 day = 14 days), but simple enough to tack on a + 1 to the end of the final select if you want to handle the boundry days differently.
Note that the math here could pretty easily be moved into a function, which would allow you to clean your SQL up. Let's assume you created a function called GetDateTimeAsInt which holds the math; your SQL could be as simple as
DECLARE #start INT = GetDateTimeAsInt('2011-01-01'),
#end INT = GetDateTimeAsInt('2011-04-15')
SELECT #end - #start -- may need to add 1 here
In my testing, this seems to work. It will return the same result as the DATEDIFF function for the date range you specify in your post, but this is because there are 2 days with 31 days and 1 day with 28, so effectively, Jan - April have 30 days each. If you use it with a wider date range, you'll begin to get different results with my code vs. the DATEDIFF function.
Hope this helps.
I use PERIODDIFF. To get the year and the month of the date, I use the function EXTRACT:
SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;
T-sql
SELECT DATEDIFF(dd, "2011-01-01","2011-04-15")

TSQL DateTime Comparison

What I am trying to do is get a result from sql where the dates are in a certain range but its not working correctly, here is my query.
DECLARE #CurrDate DATETIME
SET #CurrDate = GETDATE()
SELECT dbo.ProductDetails.PartnerID
,dbo.ProductDetails.ProductID
,dbo.Products.ProductName
,StartDate
,EndDate
FROM dbo.ProductDetails
INNER JOIN dbo.Products
ON dbo.ProductDetails.ProductID = dbo.Products.ProductID
WHERE CONVERT(VARCHAR(10),StartDate,111) <= #CurrDate
AND CONVERT(VARCHAR(10),EndDate, 111) >= #CurrDate
but when the Enddate = #CurrDate the row does not show, but if i make that date just one day higher it gets displayed. Am i doing anything wrong? Any advice will do, thanks.
GetDate() returns date and time, while your conversion to varchar strips away the time part (I'm suspecting that's all it's actually supposed to do). So you would need to do the same conversion for #CurrDate.
If what you want is to simply consider the date only (ignoring the time part), you could use DATEDIFF instead of converting to varchar (see here); example:
DECLARE #CurrDate DATETIME
SET #CurrDate = GETDATE()
SELECT dbo.ProductDetails.PartnerID, dbo.ProductDetails.ProductID,
dbo.Products.ProductName , StartDate, EndDate
FROM dbo.ProductDetails INNER JOIN
dbo.Products ON dbo.ProductDetails.ProductID = dbo.Products.ProductID
-- where StartDate is on the same day or before CurrDate:
WHERE DATEDIFF(day, StartDate, #CurrDate) >= 0 AND
-- and where EndDate is on the same day or after CurrDate:
DATEDIFF(day, EndDate, #CurrDate) <= 0
If you want only DATE comparison, without time use the
cast(CONVERT(varchar, StartDate, 112) as datetime)
I am quite sure that the comparison takes into account the time as well as the date, in which case if the dates are the same but the current time is greater than the time being compared to you won't get that row as a result.
So, what you need to do is just extract the date part and compare those.
GETDATE() gives you date and time
if yours column have only date
then
CONVERT(VARCHAR(10),StartDate,111) <= #CurrDate
can give you unexpected result
remember
19.12.2011 14:41 > 19.12.2011 00:00
If you are using SQL 2008 or later, and wanting to compare only the date, not the time, you can also do:
Cast(StartDate as Date)
(This avoids having to convert to a string.)

SQL SERVER passing getdate() or string date not working correctly

CREATE PROCEDURE sp_ME
#ID int,
#ThisDate datetime = null
AS
SET NOCOUNT ON
IF #ThisDate IS NULL
BEGIN
SET #ThisDate = CURRENT_TIMESTAMP
END
DECLARE #intErrorCode int,
#QBegin datetime,
#QEnd datetime
SELECT #intErrorCode = ##ERROR
IF #ThisDate BETWEEN '01/01/' + CONVERT(VARCHAR(4), YEAR(#ThisDate))
AND '03/31/' + CONVERT(VARCHAR(4), YEAR(#ThisDate))
BEGIN
Select #QBegin = DATEADD(s,0,CAST ('10/01/' AS varchar(6) ) +
CONVERT(VARCHAR(4),DATEPART (year,#ThisDate)-1))
Select #QEnd = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#QBegin)+3,0))
SELECT * FROM QUERY
WHERE MEID = #ID
AND mydate >= #QBegin
AND mydate <= #QEnd)
END
SELECT #intErrorCode = ##ERROR
IF (#intErrorCode <> 0) GOTO ErrHandler
ErrHandler:
RETURN #intErrorCode
GO
It returns a dataset when you leave it blank and it assumes and fills in the date, however when you plug in a date it just states "The command completed successfully."
Any help would be more than appreciated.
At a guess, you need to query the previous quarter's results, which would just be this query:
SELECT * FROM QUERY
WHERE MEID = #ID
AND mydate >= DATEADD(quarter,DATEDIFF(quarter,'20010101',#ThisDate),'20001001'),
AND mydate < DATEADD(quarter,DATEDIFF(quarter,'20010101',#ThisDate),'20010101'))
And get rid of that big if condition, etc.
You could also get rid of the first if, if you put COALESCE(#ThisDate,CURRENT_TIMESTAMP) in the above, where I currently have #ThisDate.
I use the DATEADD(quarter,DATEDIFF(quarter,'20010101',#ThisDate),'20001001') pattern for a lot of datetime manipulation. It let's you achieve a lot in a few operations. In this case, it's the difference between the two dates ('20010101','20001001') which is giving us the previous quarter.
You'll frequently encounter the DATEADD/DATEDIFF pattern in questions involving removing the time portion from a datetime value. The canonical version of this is DATEADD(day,DATEDIFF(day,0,#Date),0). But the pattern can be generally extended to work with any of the datetime components. If you choose month rather than day, you'll get midnight at the start of the first of the month (of the day you've supplied)
Where it gets tricky is when you use dates (instead of 0), and especially if you don't use the same date for both calculations. This allows you to apply an additional offset that seems almost "free" - you're already using this construct to remove the time component, the fact that you can compute e.g. the last date in a quarter/month/etc is a bonus.