date between query issue in sqlite3 - c

In my data base , i was stored one student data in the following date format is 07-03-2013(dd-mm-yyyy). For example the start date greater than the end date ,no row return in the results.
For Ex.
select student_name from general_details where join_date between '11-02-2013' and '08-03-2013'
it returns 0
if start date less than the end date
select student_name from general_details where join_date between '01-02-2013' and '08-03-2013'
it returns row value 1;
Please suggest ,thanks in advance

The dates are compared alphabetically and not as datetime stamps.
If you can influence how the dates are stored, use a format such as ISO-8601 yyyy-MM-dd or unix epoc timestamps to make the comparisons work.
If you cannot influence the data, you can convert the values in SQL by picking up the components with substr() and concatenating together with ||, like this:
substr(join_date,7,4) || substr(join_date,4,2) || substr(join_date,1,2)

Related

SQL Server - Select between 2 dates of type DD/MM/YYYY

I want to query a datetime field using a range of dates provided in the format DD/MM/YYYY.
I know that to convert datetime to a DD/MM/YYYY format that I can use:
CONVERT(CARCHAR(10), ORDERDATE,103)`
And this works fine when querying a single date, eg:
SELECT DISTINCT
CONVERT(DATE, ORDERDATE),
CONVERT(CARCHAR(10), ORDERDATE,103)
FROM ORDERS
WHERE CONVERT(CARCHAR(10), ORDERDATE,103) = '19/10/2017'
Returns: 2017-10-19, 19/10/2017
However it does not work on a range of dates, eg:
WHERE CONVERT(CARCHAR(10), ORDERDATE,103) BETWEEN '17/10/2017' AND '19/10/2017'
Returns:
2014-02-05
2016-12-12
2013-04-30
I know there are hundreds of threads about SQL dates, but they all seem to be regarding reformatting the output and not preparing the input. Do I need to reformat my DD/MM/YYYY inputs?
To query a range of dates, use the DATE-datatype instead of VARCHAR.
If datatype of column ORDERDATE is DATETIME:
WHERE CONVERT(DATE, ORDERDATE) BETWEEN
CONVERT(DATE, '17/10/2017', 103) AND CONVERT(DATE, '19/10/2017', 103)
The conversion of ORDERDATE is only necessary if the start and end date are the same. (in this case, when no conversion is done, only dates with a time value of '00:00:00.000' will be returned)
EDIT:
To omit the conversion of ORDERDATE you can add the time to the dates and convert them to DATETIME instead of DATE, like this:
WHERE ORDERDATE BETWEEN
CONVERT(DATETIME, '19/10/2017 00:00:00') AND CONVERT(DATETIME, '19/10/2017 23:59:59.999');
Or even simpler, like suggested in #Used_By_Already's answer:
WHERE ORDERDATE >= '20171017' AND ORDERDATE < '20171020' --Note the end date is here +1 day
SQL Server date information should NOT be stored "in a format". If if they are literally stored in that format then they are NOT dates as far as the database is concerned (they are "strings" that look like dates) and you will have a nightmare to deal with if they are DD/MM/YYYY because they simply will not behave like dates should.
There are several specific data types in SQL Server for date/time information (datetime, datetime2, smalldatetime, date, time) but ALL of these do not store data in a human readable format at all. Instead they stored as groups of numbers, which will be displayed in a human readable manner, and in your case - by default - you are seeing then in DD/MM/YYYY format. A user in China might prefer to see a date in YYYY.MM.DD or in the USA as MM/DD/YYYY. This is possible because a human format is applied on top of the numbers that are stored before they get displayed.
So. In SQL Server there is a "safe" date literal in the form of 'YYYYMMDD' and this may be used without the need to CONVERT or CAST:
IF your [ORDERDATE] column is a date (or smalldatetime/datetime/datetime2) then this will work:
WHERE ORDERDATE BETWEEN '20171017' AND '20171019'
OR, you may explicitly convert a string to but you need a "style number" to be present to make these fully reliable. Style 103 for example is for DD/MM/YYYY
WHERE ORDERDATE BETWEEN CONVERT(date, '17/10/2017',103) AND CONVERT(date, '19/10/2017',103)
Although "between" has been used in the discussion above a far more reliable method of forming date ranges is to NOT use "between", instead do it this way:
WHERE ORDERDATE >= '20171017' AND ORDERDATE < '20171020'
With this pattern (note the second day is now +1) it does not matter which date precision is stored in the column. For example, see Bad habits to kick : mis-handling date / range queries

convert string from MM/DD/YYYY to YYYYMMDD

My date column is stored as a CHAR and in YYYYMMDD format. The string I have to search from this column is in MM/DD/YYYY format. How could I change it to YYYYMMDD. Also if my parametr is passed NULL to the query I do not include the DOB search in the WHERE clause
select *
from ona
left join mnv on ona.xyz = mnv.xyz
where (coalesce(to_date(mnv.DOB,'YYYYMMDD'),to_date('1901-01-01','YYYY-MM-DD')) OR '{BirthDate}' IS NULL)
It is not suggested to store dates as string, mainly due to this particular reason. So try to change your column datatype if possible to avoid this in future.
For now, you can compare it, by converting both of the strings to date, with to_date function.
select something from some_table where
to_date(date_Column,'YYYYMMDD')=to_date(search_value,'MM/DD/YYYY');
As you asked in comments, it is possible to do it by manupulating the strings also however I think comparing by dates would be faster and less prone to inaccuracy.
Update after seeing your query.
You are not converting BirthDate to date and also there is no = to compare in your query. Assuming that BirthDate is a string with MM/DD/YYYY format, use something like below.
select * from ona left join mnv on ona.xyz = mnv.xyz
where
to_date(mnv.DOB,'YYYYMMDD') = to_date(BirthDate,'MM/DD/YYYY')
and mnv.DOB is not null
and BirthDate is not null.

SQL update based on query results with two parameters

I've created a virtual table in SQL Server that has 28 days from the current date and each date has rows for time that range from 12-10 pm incremented by 15 min and another value to indicate that it's turned on/off for availability, so it would be something like this:
date time onoff
-------------------------------------------------
2015-04-08 12:00 1
2015-04-08 12:15 1
....continue until 22:00 then start next day
2015-04-09 12:00 1
..... continue for 28 days
I'd like to update the availability based on a query from another table which would return the date, start and end time...
So far I came up with this
update table1
set onoff = 0
where tbl1date in (select tbl2date from table2 where userid = 1)
The problem I'm having is adding in the between certain hours part of the equation and I'm not sure how to do something like this in SQL or how to even search for the answer based on not being able to word it properly...
Can someone help or point me in the right direction?
use a DATETIME, don't use separate DATE and TIME fields.
I think you should take a look at DATEDIFF (https://technet.microsoft.com/pl-pl/library/ms189794(v=sql.110).aspx) function.
Your where query could look like this:
update table1 set onoff = 0
where
DATEDIFF(minute, <MIN_RANGE>, tbl1date) >= 0 and
DATEDIFF(minute, tbl1date, <MAX_RANGE>) >= 0
How you calculate MIN_RANGE and MAX_RANGE depends on your table2 structure.
As suggested, if you have control over the structure, use datetime fields as they are easier to do the comparisons on. I'm going to assume you don't have control over the structure.
In order to compare the datetimes you need to create them from your separate date and times. You can either parse the time field for the hours and minutes and use DATEADD to add the appropriate offsets to the date, or you can use CONVERT to interpret a date time string as a date. Something like
CONVERT(datetime, SUBSTRING(CONVERT(varchar, tbl1date, 121), 1, 10) + ' ' + tbl1time, 121)
What this does is to convert the date to odbc cannonical format and throwaway the time part as it takes only the first 10 characters. Then it appends the time and interprets the whole string as a odbc cannonical datetime string. That format is yyyy-mm-dd hh:mi:ss.mmm. The hours are based on 24 hours. So if your times are in AM/PM format you're going to have to convert them.
If your other table has separate date and times you'd use a similar expression to combine them.
Once you have the datetimes you can do something like this
UPDATE table1
SET onoff = 0
WHERE <expression above> BETWEEN (SELECT min_value FROM table2) AND (SELECT max_value FROM table2)

Comparing dates with current date in Sql server

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

Select condition on date for datetime field

I want to impose date condition on a date time field in SQL Server.
The datetime field is like this 2011-01-19 17:57:18.350 and when I execute below query it yields no results.
select top 1000 *
from [dbo].[RouteState]
where convert (date, logtime, 101) = '12-01-2015'
Can someone help me what's going wrong here?
There is no need to convert the datetime column to anything. Use a closed-open interval instead and change the format of your string literal to yyyymmmdd to make sure that SQL Server will interpret the date value in the same way regardless of regional and date format settings.
select top 1000 *
from [dbo].[RouteState]
where logtime >= '20150112' and
logtime < '20150113';
For more info on casting a column to date you can have a look at Cast to date is sargable but is it a good idea?

Resources