Sql Server- Get the dates from the database between the range supplied - sql

I have an issue to get the records if the FtableID at any point in the range (Start date and End date) has a StatusID=2.
My table Structure is
ID FTableID StatusID AddedOn
75324 53591 1 2019-03-17 06:48:14.490
75325 53591 2 2019-03-18 06:48:14.663
75326 53591 3 2019-03-19 06:54:20.830
#StartDate Datetime='2019/03/17 23:00:00' ,
#EndDate Datetime='2019/03/20 23:59:59'
Select ID, FTableID,StatusID,AddedOn from MyTableName where FTableID=53591
And StatusID=2 and AddedOn <= #EndDate
I know my query is wrong and it gives the record even when I pass the #startdate after its status gets changed to 3 (Completed)
I am confused to set the start date filter.
I need to check if this FtableID record is in status id =2 at any point in the range supplied
The record should come If I pass the #StartDate Datetime='2019/03/18 23:00:00', #EndDate Datetime='2019/03/20 23:59:59' because it is in this range it was in the status=2
The record should not come If I pass the #StartDate Datetime='2019/03/19 23:00:00', #EndDate Datetime='2019/03/20 23:59:59' because it was convertted to statusID=3
Please suggest me on this. Thanks in advance.

use this
select *
from YourTableName
where AddedOn between (#StartDate and #EndDate)
and StatusID=2

One method uses exists.
I would simplify your date arithmetic as well, so:
declare #StartDate datetime '2019-03-17 23:00:00';
declare #EndDate datetime = '2019-03-20'
select t.*
from mytablename t
where exists (select 1
from mytablename t2
where t2.ftableid = t.ftableid and
t2.statusid = 2 and
t2.AddedOn >= #StartDate and
t2.AddedOn < #EndDate
);

Related

Floor() function on a datetime - SQL Server

http://sqlfiddle.com/#!18/639ec/2
CREATE TABLE TEST
(
ID INT,
OrderNo int,
DateReceived datetime
)
INSERT INTO TEST (ID,OrderNo,DateReceived)
VALUES ('1', '3454', '07-20-2018 00:00:00')
Query:
DECLARE #StartDate datetime,
#EndDate datetime,
#FlooredStart datetime ,
#FlooredEnd datetime
SET #StartDate = '07-20-18'
SET #EndDate = '07-20-18'
SET #FlooredStart = CAST(FLOOR(CAST(#startDate AS FLOAT)) AS DATETIME)
SET #FlooredEnd = DATEADD(d, 1, CAST(FLOOR(CAST(#endDate AS FLOAT)) AS DATETIME))
SELECT * FROM TEST
WHERE DateReceived = #FlooredStart and DateReceived < #FlooredEnd
In my live version if the date received is left blank it defaults to the time 12:00:00AM of that day. So for this example if i search for orders on the 07-20-18 it wont return the order that was placed at 12:00:00AM of the 07-20-18.
So i figure to add >= to the clause
DECLARE #StartDate datetime,
#EndDate datetime,
#FlooredStart datetime ,
#FlooredEnd datetime
SET #StartDate = '07-20-18'
SET #EndDate = '07-20-18'
SET #FlooredStart = CAST(FLOOR(CAST(#startDate AS FLOAT)) AS DATETIME)
SET #FlooredEnd = DATEADD(d, 1, CAST(FLOOR(CAST(#endDate AS FLOAT)) AS
DATETIME))
SELECT * FROM TEST
-- WHERE DateReceived BETWEEN #StartDate AND #EndDate
WHERE DateReceived >= #FlooredStart and DateReceived < #FlooredEnd
Result:
| ID | OrderNo | DateReceived |
|----|---------|----------------------|
| 1 | 3454 | 2018-07-20T00:00:00Z |
I was just wondering if i had this logic correct? And can anyone explain to me exactly what the floor() function is doing. I understand that its calculating the first day of year/month but is that needed here? I looked online and i could'nt find a definitive answer anywhere.
Thanks
Instead of using floor to "truncate" the time part, use the date-only date type :
DECLARE #StartDate date = '20180720', #EndDate date='20180720'
SELECT * FROM TEST
WHERE cast(DateReceived date) between #startdate and #enddate
or, for a single date only :
SELECT * FROM TEST
WHERE cast(DateReceived date) = #startdate
Note that I'm using the unseparated date literal. This is the only unambiguous date format. The other unambiguous format is the full ISO8601 format for the datetime types. Two-digit years are just begging for incorrect interpretation way.
cast(DateReceived date) will convert the datetime values in DateReceived into date values. Usually, it's a bad idea to apply functions to fields because it prevents the query optimizer to use any indexes. SQL Server understands cast( ... as date) though and converts :
cast(DateReceived date) = #startdate
To a range query equivalent to DateReceived between #startdate at 00:00 but before the next day at 00:00 , allowing it to use any indexes on DateReceived

How to get all dates between two dates in sql server

I want to get all dates between startend and Enddate.I used between to get the desired result. But the between function skipping the current date.
Declare #StartDate Datetime ='2014-04-01 11:13:37'
,#EndDate datetime ='2014-04-04 11:13:37'
Query:-
Select * from table where date between #Startdate and #EndDate
Current Result:-
2014-04-02 11:13:37
2014-04-03 11:13:37
2014-04-04 11:13:37
Expected result:-
2014-04-01 11:13:37
2014-04-02 11:13:37
2014-04-03 11:13:37
2014-04-04 11:13:37
You could create a procedure like this:
CREATE PROCEDURE getAllDaysBetweenTwoDate
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS
BEGIN
DECLARE #TOTALCount INT
SET #StartDate = DATEADD(DAY,-1,#StartDate)
Select #TOTALCount= DATEDIFF(DD,#StartDate,#EndDate);
WITH d AS
(
SELECT top (#TOTALCount) AllDays = DATEADD(DAY, ROW_NUMBER()
OVER (ORDER BY object_id), REPLACE(#StartDate,'-',''))
FROM sys.all_objects
)
SELECT AllDays From d
RETURN
END
GO
Courtesy: Find All the Days Between Two Dates
Your query works for me perfectly.
DECLARE #StartDate DATETIME = '2014-04-01 11:13:37',
#EndDate DATETIME = '2014-04-04 11:13:37';
WITH cte_dates
AS
(
SELECT DATEADD(MONTH,-1,#startDate) dates --get dates from a month before start date
UNION ALL
SELECT DATEADD(DAY,1,dates)
FROM cte_dates
WHERE dates < DATEADD(MONTH,1,#EndDate) --up to a month after end date
)
SELECT dates
FROM cte_dates
WHERE dates BETWEEN #Startdate AND #EndDate
Results:
dates
-----------------------
2014-04-01 11:13:37.000
2014-04-02 11:13:37.000
2014-04-03 11:13:37.000
2014-04-04 11:13:37.000
This means that it's probably an issue with your data, specifically the time section. If you don't need to look at time and only need specific dates, try this instead:
DECLARE #StartDate DATE = '2014-04-01',
#EndDate DATE = '2014-04-04';
SELECT *
FROM yourTable
WHERE CAST([date] AS DATE) BETWEEN #startDate AND #EndDate
You Can Try this
Declare #StartDate Date ='2014-04-01'
,#EndDate date ='2014-04-04'
(OR)
Declare #StartDate Datetime ='2014-04-01 00:00:00'
,#EndDate datetime ='2014-04-04 12:59:59'
Query:-
Select * from table where date between #Startdate and #EndDate

get last date in tsql

i show you my logic is getting error only when month is December
declare #startDate datetime
declare #endDate datetime
set #startDate = convert(varchar(2),#month)+'/1/'+ convert(varchar(4),#year)
set #endDate = dateadd(DD,-1,(convert(varchar(2),#month+1)+'/1/'+convert(varchar(4),#year)))
while(#startDate < #endDate+1)
begin
insert into #tempday
select #startDate
set #startDate = dateadd(day, 1, #startDate )
end
please help
Once you have #startdate, use:
set #enddate = dateadd(day,-1,dateadd(month,1,#startdate))
And I don't think you mean plsql...
There are other things you could think about too, such as not using a while-loop. Why not query a table that has plenty of rows (such as sys.all_columns) and use:
insert #tempday
select top (datediff(day,#startdate,#enddate)+1)
dateadd(day,row_number() over (order by (select 1))-1,#startdate)
from sys.all_columns;
In case of December #month+1 will get you 13 which is not a valid month number

Having issues with dates in SQL

I'm writing a report that needs to collect data each day, between 0900hs and 1700hs.
I thought it would be fine as follows:
cast(convert(char(8),t.trxtime,112)as time)
between CONVERT(VARCHAR(5),getdate(),108) >= '09:00'
and CONVERT(VARCHAR(5),getdate(),108) < '17:00'
....BUT no cigar.
Thank you!!!
Hmmm, you could just use datepart():
where datepart(hour, t.trxtime) between 9 and 16 and
cast(t.trxtime as date) = cast(getdate() as date)
I'm not sure if the date comparison is actually necessary.
You could do something like this (assuming you mean actually for the current date, and not for every date in a range:
declare #startDate datetime
declare #endDate datetime
select #startDate = '2014-11-03 09:00:00',
#endDate = '2014-11-03 17:00:00'
select *
from table
where myDate between #startDate and #endDate
if you did mean between 0900 and 1700 for each day, you could do:
declare #startDate datetime
declare #endDate datetime
select #startDate = '2014-10-03',
#endDate = '2014-11-03' -- note i'm still limiting it to a range of ~1 month
select *
from table
where myDate between #startDate and #endDate
and datepart(hour, myDate) between 9 and 17

Selecting records using between operator SQL Server

I am getting confusing in writing the best stored procedure for my requirement.
I am filtering records based on StartDate and EndDate.
So I want to get records whose StartDate and EndDates are between StartDate & EndDate range.
Previously I had asked this question Here in SE, and got some answers. But later I found that the query is not giving me correct results.
So the answer I found there is:
select *
from tbl
Where (Event_Startdate between #StartDate and #EndDate)
and (Event_Enddate between #StartDate and #EndDate)
Lets say I have records :
If I execute the above query with inputs like:
#StartDate = '1/1/2000',
#EndDate = '5/16/2014',
The query above gives no records at all right.. because here Event_StartDate is between the StartDate and EndDate, where as End Date is not between the range.
But what I want is if the StartDate or EndDate is between range, then it should be selected.
Then immediately OR operator came into my mind, I tried by changing And to OR in my query
select *
from tbl
Where (Event_Startdate between #StartDate and #EndDate)
OR (Event_Enddate between #StartDate and #EndDate)
It gave the correct answer in this situation.
But the problem with this query is it doesn't check the second condition, which is after 'OR' If the first condition is true. Suppose if i gave input as:
#StartDate = '1/1/2000',
#EndDate = '7/25/2014'
It will select all records in the table because StartDate is in between 1/1/2000 to 7/25/2014 which is true, so it does nt check whether EndDate is in between the range or not, it does'nt care about EndDate.
I hope my problem is clear to u..Please somebody help with this...
Try this
select * from (
select * from tbl Where Event_Startdate between #StartDate and #EndDate
) AS A
Where Event_Enddate between #StartDate and #EndDate
This will work for sure
select *
from tbl
Where ( #StartDate between Event_Startdate and Event_Enddate
or Event_Startdate between #StartDate and #EndDate)
and ( #EndDate between Event_Startdate and Event_Enddate
or Event_Enddate between #StartDate and #EndDate)
If you want rows whose ranges are completely within the bounds of the specified range, specify that Event_Startdate should be not earlier than #StartDate and Event_Enddate not later than #EndDate:
WHERE Event_Startdate >= #StartDate
AND Event_Enddate <= #EndDate
If You need to filter all overlaping intervals(inner and outer)and optionaly with NULLs in Event_Startdate and Event_Enddate, try this:
select *
from tbl
Where
1=CASE WHEN Event_Startdate IS NOT NULL AND Event_Enddate IS NOT NULL THEN
CASE WHEN #StartDate<=Event_Startdate AND #EndDate>=Event_Enddate THEN 1
WHEN #StartDate>=Event_Startdate AND #EndDate<=Event_Enddate THEN 1
WHEN #StartDate<=Event_Startdate AND #EndDate BETWEEN Event_Startdate AND Event_Enddate THEN 1
WHEN #EndDate>=Event_Enddate AND #StartDate BETWEEN Event_Startdate AND Event_Enddate THEN 1
ELSE 0 END
WHEN Event_Startdate IS NULL AND Event_Enddate IS NOT NULL AND #StartDate<=Event_Enddate THEN 1
WHEN Event_Enddate IS NULL AND Event_Startdate IS NOT NULL AND #EndDate>=Event_Startdate THEN 1
ELSE 0 END
well you can see in the data:
your date are different.
in the db, it is
'yyyy/mm/dd'
and your variables are
'dd/mm/yyyy'