Select data from date range between two dates and times - sql

I have pretty much the exact same question as logged here
Select data from date range between two dates
But when I used the solution given it does not work for me. Only difference is that my table has date and time in the one column. So I want to be able to return all values that fall within the date range
I have this so far but not working
SELECT * FROM aview
WHERE startDate BETWEEN ('2017-11-25 11:27:00.000', '2018-11-25 11:27:00.000') OR
leftdate BETWEEN ('2017-11-25 11:27:00.000', '2018-11-25 11:27:00.000') OR
start_Date <= '2017-11-25 11:27:00.000' AND left_dept_date >= '2018-11-25 11:27:00.000'

I've never seen BETWEEN(from,to) as a pattern in an sql query - you're making it look like a function call similar to SUBSTRING(column, index) when it doesn't work like that. Try this:
SELECT * FROM aview
WHERE
startDate BETWEEN CONVERT(datetime, '2017-11-25 11:27:00.000', 121) AND CONVERT(datetime, '2018-11-25 11:27:00.000', 121) OR
leftdate BETWEEN CONVERT(datetime, '2017-11-25 11:27:00.000', 121) AND CONVERT(datetime, '2018-11-25 11:27:00.000', 121) OR
start_Date <= CONVERT(datetime, '2017-11-25 11:27:00.000', 121) AND left_dept_date >= CONVERT(datetime, '2018-11-25 11:27:00.000', 121)
There's no syntax error with this query (see http://sqlfiddle.com/#!6/9eecb7db59d16c80417c72d1e1f4fbf1/16114 ) when the columns are proper dates, so the only thing left is a flaw in the view code, doing a bum conversion of data - for example if your view is converting a string of "12/31/2017" into a date, but doing it as if it was "dd/mm/yyyy", or perhaps converting a "2107-12-31" with a typo in the year, into a smalldatetime type that doesn't support years beyond 2079
See https://learn.microsoft.com/en-us/sql/t-sql/language-elements/between-transact-sql

I am not sure about syntax for BETWEEN Clause is upgraded in sql Server 2012. but it seems like that you have syntax error in between clause
SELECT *
FROM aview
WHERE ( startDate BETWEEN '2017-11-25 11:27:00.000' AND '2018-11-25 11:27:00.000' AND
leftdate BETWEEN '2017-11-25 11:27:00.000' AND '2018-11-25 11:27:00.000' ) OR
start_Date <= '2017-11-25 11:27:00.000' AND
left_dept_date >= '2018-11-25 11:27:00.000'

You copied the wrong answer. The BETWEEN syntax is invalid.
Then if you want to know whether a record's range overlaps with a given range, why are there four columns in your table and query? It should be two: the start and the end.
SELECT *
FROM aview
WHERE start <= '2018-11-25T11:27:00.000' AND end >= '2017-11-25T11:27:00.000';
Or if you want the record's whole range within the given range:
SELECT *
FROM aview
WHERE start >= '2017-11-25T11:27:00.000' AND end <= '2018-11-25T11:27:00.000';

SELECT * FROM USERContracts C
WHERE
(C.UCFromDate > ='2008-01-01' AND C.uCFromDate <='2020-02-06' )
OR (C.UCToDate < ='2008-01-01' AND C.uCToDate >='2020-02-06')
order by USERID

Related

SQL Assistance - SELECT/WHERE/CASE?

I am banging my head against the desk here trying to work something out in SQL, I understand the logic and I can easily complete the task in Excel however where is the fun in that :)
The database in question as a WorkOrder table and I am selecting the following columns:
SELECT WorkOrderNumber,
WorkOrderDescription,
WorkOrderHistoryDescription,
RaisedDateTime,
FinishedDateTime
What I need I am trying to do is return all work orders raised within a given month which is easy enough:
WHERE RaisedDateTime >= CONVERT(DATETIME, '2014-12-01' ) and <= CONVERT(DATETIME, '2014-12-31' )
The kicker is I also want those return those records that were raised prior to but were closed in the given month, I tried the following which appeared to work:
WHERE ( RaisedDateTime >= CONVERT(DATETIME, '2014-12-01' ) AND RaisedDateTime <= CONVERT(DATETIME, '2014-12-31' ) )
OR ( FinishedDateTime >= CONVERT(DATETIME, '2014-12-01' ) AND FinishedDateTime <= CONVERT(DATETIME, '2014-12-31' ) AND RaisedDateTime < CONVERT(DATETIME, '2014-12-01' ) )
However when I inserted PreventativeMaintenanceID IS NULL after the statement above I found work orders that had a value in that column, if I just have the first line of the WHERE statement everything works fine.
Any ideas/pointers of where I might be going wrong? I was looking to see if I could use a CASE statement however I just couldn't get it to work.
It's hard to tell without knowing how exactly your full query looks but try grouping your criteria other than that line, and then add that line after the grouped criteria, like this:
SELECT WorkOrderNumber,
WorkOrderDescription,
WorkOrderHistoryDescription,
RaisedDateTime,
FinishedDateTime
from tbl
WHERE (
(RaisedDateTime between CONVERT(DATETIME, '2014-12-01') AND
CONVERT(DATETIME, '2014-12-31')) OR
(FinishedDateTime between CONVERT(DATETIME, '2014-12-01') AND
CONVERT(DATETIME, '2014-12-31') AND
RaisedDateTime < CONVERT(DATETIME, '2014-12-01'))
)
and PreventativeMaintenanceID IS NULL
Based on your description it sounds like an order of operations issue due to the OR

sql select date range returns date outside range

Selecting aload of records based on dates, but im getting dates returned which are not inside the range any ideas?
SELECT *
FROM TABLE
WHERE (
PAYMENT_DATE >= CONVERT(DATETIME, '2010-05-06')
AND PAYMENT_DATE <= CONVERT(DATETIME, '2013-11-11')
)
This for example will return a record that has a date of "2008-04-10 00:00:00.000"
When you're not using parameters, always use the invariant datetime format:
SELECT *
FROM [Table]
WHERE ([PaymentDate] >= '20100506' AND [PaymentDate] <= '20131111')
Its good to check the range with SQL between Clause.
SELECT *
FROM table
WHERE PAYMENT_DATE BETWEEN CONVERT(datetime, '2010-05-06')
AND CONVERT(datetime, '2013-11-11')
Also, you can specify the month by its name or abbreviation, like below:
SELECT *
FROM TABLE
WHERE (
PAYMENT_DATE >= CONVERT(DATETIME, '2010-May-06')
AND PAYMENT_DATE <= CONVERT(DATETIME, '2013-Nov-11')
)
Or you can just use the BETWEEN clause to simplify the query:
SELECT *
FROM TABLE
WHERE
PAYMENT_DATE BETWEEN '2010-May-06' AND '2013-Nov-11'
Just give a try to this
this must give the expected result
SELECT *
FROM table
WHERE (Convert(datetime,PAYMENT_DATE,103) >= CONVERT(datetime, '2010-05-06')
AND Convert(datetime,PAYMENT_DATE,103) <= CONVERT(datetime, '2013-11-11'))

SQL Server 2005 extract a date from a string

I have a view I am creating and I want to group by an extracted date from a column that has a date and time. This is where I am....
SELECT
ClockCode AS MOnum, SUM(Actual_Hrs) AS Runtothours, TStamp
FROM
dbo.Raw_Booking
WHERE
(Actual_Hrs > 0) AND (ClockCode LIKE 'MO%')
AND (TStamp > CONVERT(DATETIME, '2013-01-01 00:00:00', 102))
GROUP BY
ClockCode, TStamp
so while I have it grouped by the TStamp column there is a record for each one based on the time... I am looking to get a total amount of run time for each order by date.
The TStamp column is formatted as:
2013-01-02 08:18:47.000
If you can change your schema, store it as a date to begin with. Otherwise, change your group by clause to something similar to...
GROUP BY CAST(TStamp AS DATE)
EDIT: Forgot you were in SQL 2005. You can still do something like the following, but keep in mind this should be considered an ugly, short-term, workaround. All the comments in this thread about redesigning are completely valid and should be pursued...
GROUP BY SUBSTRING(TStamp, 0, 11)
SELECT ClockCode AS MOnum
, SUM(Actual_Hrs) AS Runtothours
, TStampDate
FROM dbo.Raw_Booking
CROSS APPLY (
SELECT CONVERT(datetime, TStamp, 102) AS TStampDateTime
) AS CA1
CROSS APPLY (
SELECT DATEADD(day, DATEDIFF(day, 0, TStampDateTime), 0) AS TStampDate
) AS CA2
WHERE Actual_Hrs > 0
AND ClockCode LIKE 'MO%'
AND TStampDateTime > CONVERT(DATETIME, '2013-01-01 00:00:00', 102))
GROUP BY ClockCode
,TStampDate

Comparing results with today's date?

Is there a way to use the Now() function in SQL to select values with today's date?
I was under the impression Now() would contain the time as well as date, but today's date would have the time set to 00:00:00 and therefore this would never match?
OK, lets do this properly. Select dates matching today, using indexes if available, with all the different date/time types present.
The principle here is the same in each case. We grab rows where the date column is on or after the most recent midnight (today's date with time 00:00:00), and before the next midnight (tomorrow's date with time 00:00:00, but excluding anything with that exact value).
For pure date types, we can do a simple comparison with today's date.
To keep things nice and fast, we're explicitly avoiding doing any manipulation on the dates stored in the DB (the LHS of the where clause in all the examples below). This would potentially trigger a full table scan as the date would have to be computed for every comparison. (This behaviour appears to vary by DBMS, YMMV).
MS SQL Server: (SQL Fiddle | db<>fiddle)
First, using DATE
select * from dates
where dte = CAST(CURRENT_TIMESTAMP AS DATE)
;
Now with DATETIME:
select * from datetimes
where dtm >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
Lastly with DATETIME2:
select * from datetimes2
where dtm2 >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm2 < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
MySQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = cast(now() as date)
;
Using DATETIME:
select * from datetimes
where dtm >= cast((now()) as date)
and dtm < cast((now() + interval 1 day) as date)
;
PostgreSQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = current_date
;
Using TIMESTAMP WITHOUT TIME ZONE:
select * from timestamps
where ts >= 'today'
and ts < 'tomorrow'
;
Oracle: (SQL Fiddle)
Using DATE:
select to_char(dte, 'YYYY-MM-DD HH24:MI:SS') dte
from dates
where dte >= trunc(current_date)
and dte < trunc(current_date) + 1
;
Using TIMESTAMP:
select to_char(ts, 'YYYY-MM-DD HH24:MI:SS') ts
from timestamps
where ts >= trunc(current_date)
and ts < trunc(current_date) + 1
;
SQLite: (SQL Fiddle)
Using date strings:
select * from dates
where dte = (select date('now'))
;
Using date and time strings:
select dtm from datetimes
where dtm >= datetime(date('now'))
and dtm < datetime(date('now', '+1 day'))
;
Using unix timestamps:
select datetime(dtm, 'unixepoch', 'localtime') from datetimes
where dtm >= strftime('%s', date('now'))
and dtm < strftime('%s', date('now', '+1 day'))
;
Backup of SQL Fiddle code
There is no native Now() function in SQL Server so you should use:
select GETDATE() --2012-05-01 10:14:13.403
you can get day, month and year separately by doing:
select DAY(getdate()) --1
select month(getdate()) --5
select year(getdate()) --2012
if you are on sql server 2008, there is the DATE date time which has only the date part, not the time:
select cast (GETDATE() as DATE) --2012-05-01
Not sure what your asking!
However
SELECT GETDATE()
Will get you the current date and time
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
Will get you just the date with time set to 00:00:00
Just zero off the time element of the date. e.g.
SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
I've used GetDate as that's an MSSQL function, as you've tagged, but Now() is probably MySQL or you're using the ODBC function call, still should work if you just replace one with the other.
Not sure exactly what you're trying to do, but it sounds like GETDATE() is what you're after. GETDATE() returns a datetime, but if you're not interested in the time component then you can cast to a date.
SELECT GETDATE()
SELECT CAST(GETDATE() AS DATE)
Building on the previous answers, please note an important point, you also need to manipulate your table column to ensure it does not contain the time fragment of the datetime datatype.
Below is a small sample script demonstrating the above:
select getdate()
--2012-05-01 12:06:51.413
select cast(getdate() as date)
--2012-05-01
--we're using sysobjects for the example
create table test (id int)
select * from sysobjects where cast(crdate as date) = cast(getdate() as date)
--resultset contains only objects created today
drop table test
I hope this helps.
EDIT:
Following #dwurf comment (thanks) about the effect the above example may have on performance, I would like to suggest the following instead.
We create a date range between today at midnight (start of day) and the last millisecond of the day (SQL server count up to .997, that's why I'm reducing 3 milliseconds). In this manner we avoid manipulating the left side and avoid the performance impact.
select getdate()
--2012-05-01 12:06:51.413
select dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--2012-05-01 23:59:59.997
select cast(getdate() as date)
--2012-05-01
create table test (id int)
select * from sysobjects where crdate between cast(getdate() as date) and dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--resultset contains only objects created today
drop table test
If you have a table with just a stored date (no time) and want to get those by "now", then you can do this:
SELECT * FROM tbl WHERE DATEDIFF(d, yourdate, GETDATE())=0
This results in rows which day difference is 0 (so today).
For me the query that is working, if I want to compare with DrawDate for example is:
CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
This is comparing results with today's date.
or the whole query:
SELECT TOP (1000) *
FROM test
where DrawName != 'NULL' and CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
order by id desc
You can try this sql code;
SELECT [column_1], [column_1], ...
FROM (your_table)
where date_format(record_date, '%e%c%Y') = date_format(now(), '%e%c%Y')
You can try:
WHERE created_date BETWEEN CURRENT_TIMESTAMP-180 AND CURRENT_TIMESTAMP
This worked for me:
SELECT * FROM table where date(column_date) = curdate()

SQL BETWEEN Operator

Why am I getting '2009' data? What am i doing wrong with the WHERE Clause?
SELECT CONVERT(varchar, EventDate, 101) AS EVENTDATE,
CONVERT(varchar, ClosedDate, 101) AS CLOSEDDATED,
DATEDIFF(Day,EventDate,ClosedDate) AS DiffDate,
FROM mytable
WHERE (CONVERT(varchar, EventDate, 101) BETWEEN '04/01/2010' AND '04/30/2010')
You're doing a string comparison, which goes from left to right. '04/10/2009' is between '04/0' and '04/3'.
If the field you're comparing is a DATETIME, don't try to convert it. SQL server can convert the strings to dates and do the comparison properly.
If you use a supported date format, SQL Server will implicitly convert the string to a DATETIME:
SELECT CONVERT(varchar, EventDate, 101) AS EVENTDATE,
CONVERT(varchar, ClosedDate, 101) AS CLOSEDDATED,
DATEDIFF(Day,EventDate,ClosedDate) AS DiffDate,
FROM mytable
WHERE EventDate BETWEEN '2010-04-01' AND '2010-04-30'
Your query is just doing string comparison, which has no bearing on date spans.
Your WHERE clause may be doing string comparison instead of date comparison. If you want to do a date comparison you can change
CONVERT(varchar, EventDate, 101)
to
CAST (CONVERT(varchar, EventDate, 101) AS DATETIME)
You really don't need all the conversion. The dates from the calendar will have the right start and end times. You also want to consider events that might go past the end date or start before the date and end within the date range. Or finally start before and go past...
Here's some code we use
(EventStartDtTm >= startDt and EventStartDtTm <= endDt)
|| (EventStartDtTm <= startDt and EventEndDtTm >= startDt)
-- patrick