I'm new to MS Access and having trouble with using the BETWEEN AND function when applying to dates.
SELECT EmployeeID, FirstName, LastName, StartDate
FROM Chefs
WHERE StartDate BETWEEN #01/12/2015# AND #31/12/2015#;
The above gives me entries with the correct dates as well as entries with dates before the range, but not after.
Changing to
WHERE StartDate BETWEEN #30/11/2015# AND #31/12/2015#;
gives me the correct answer. Can someone tell me why the first query doesn't work?
EDIT: Working with date format dd/mm/yyyy. DataType is Date/Time with General Date format.
The reason for your trouble is that Access SQL first tries if the format mm/dd/yyyy makes sense. 01/12/2015 does (reads as 2015-01-12), while 30/11/2015 does not. Next it tries dd/mm/yyyy which will succeed for 30/11/2015 (reads as 2015-11-30). Finally, it will try yyyy/mm/dd.
Thus, as Hans writes:
Many experienced Access developers default to a yyyy-mm-dd to avoid
ambiguity.
However:
If you don't like that, dd mmm yyyy should work.
is doomed to fail in any non-English environment, as mmm will be localized.
So stick to the ISO sequence yyyy-mm-dd or use DateSerial:
WHERE StartDate BETWEEN DateSerial(2015, 12, 1) AND DateSerial(2015, 12, 31);
Related
Hi there please help me .
I'm using this code
Weekstart = DATEDD(Wk, DATEDIFF(d,0,CONVERT(DATE, GETDATE(),103)) / 7,0)
This above query is given me the output in this format '2022-02-07 00:00:00.000' however I want the date in this format '07-Feb-22'
Some things to avoid:
Shorthand like Wk and d - this isn't code golf
Magic dates like 0 - again, not code golf
Style 103 doesn't belong here at all, that is when you are taking a string in a regional format (which you also should avoid), not when converting a datetime to a date
Lots more things to avoid here: Dating Responsibly
I would do it this way. Use a base date that you know falls on the same weekday that you consider the start of the week:
DECLARE #base date = '20180101';
SELECT Weekstart = REPLACE(CONVERT(char(9),
DATEADD(WEEK, DATEDIFF(DAY, #base, GETDATE())/7, #base), 6),' ','-');
The only magic / shorthand in here is the style number, 6, which is a very specific way to coerce a date/time into a specific format (discover them all here). Some will suggest the built-in FORMAT() function, which matches capability in other languages like C#, but I suggest avoiding it. Not only is it not available in flavors of SQL Server that don't support CLR or x64 (like Azure SQL Edge), the overhead is substantial.
In my application client can provide date in any formats and I have to display given date in dd/mm/yyyy format only.The date formats are as-
1. dd-mmm-yyyy (Ex- 21-Jan-2019)
2. dd/mm/yyyy (Ex- 02/03/2019)
3. mm/dd/yyyy (Ex- 04/23/2019)
4. dd.mm.yyyy (Ex- 08.02.2019)
5. dd mmmm yyyy (Ex- 13 March 2019)
6. yyyy-mm-dd (Ex- 2019-03-04)
7. mmmm dd, yyyy (Ex- January 23, 2019)
Pls suggest how can I use regex for identifying date format and then convert into desired format.
It has already been mentioned that your options (2) and (3) pose an existential problem for solving this problem. So, this answer ignores that problem.
SQL Server is pretty good about figuring out dates. So, you can try:
select try_convert(date, col)
This will return NULL values for unknown date formats. You can also look for particular formats:
select coalesce(try_convert(date, col),
try_convert(date, col, 101),
try_convert(date, col, 104),
try_convert(date, col, 120),
. . .
)
The expressions can be more complicated than try_convert() if you need to munge the string value before attempting a conversion.
The example for format 2 in your question is a great example of why this can't be done, i.e. it could be interpreted as either format 2 or 3.
You would need better control over your incoming data, which I think would necessarily require a manual element.
You could perhaps have a rule around which clients are sending dates in which format, if you are pulling some kind of client name/ID into the database, and then you could run the string value through a date conversion function which would be tailored to a specific client or group of clients, but even then, you'd have to trust that this would remain consistent over time.
When reading those invoices, can't you find the countryCode and instead of setting rules on each vendor, make rules by country?
SELECT CONVERT(VARCHAR(n), GETDATE(), style)
Style Standard
100 Default for datetime and smalldatetime
110 USA
111 JAPAN
112 ISO
https://tableplus.io/blog/2018/09/sql-server-date-format-cheatsheet.html
I wrote a SQL query to have the results from 2016 Apr 01 to 2016 May 01.
When I wrote:
where a.DateIntervention >= '2016-04-01'
and a.DateIntervention < '2016-05-01'
I obtain the results from 2016 Jan 04 00:00:00.000, so it is reading my dates as ydm, although the results show the date format as ymd (2016-01-04 00:00:00.000)
And when I ask the system about the date format it tells me it is dmy (!)
How to change this setting so that I can write my queries like ymd and continue obtaining the results like ymd?
In SQL Server, you don't need to. If you drop the hyphens then the strings will be interpreted using YYYYMMDD:
where a.DateIntervention >= '20160401' and a.DateIntervention < '20160501'
I prefer the hyphens because they are more readable, accepted in most databases, and generally work in SQL Server. There are particular settings where they don't work, but 'YYYYMMDD' is always interpreted as a date.
I should add, you can throw in a cast()/convert() if you like:
where a.DateIntervention >= cast('20160401' as date) and
a.DateIntervention < cast('20160501' as date)
There's no built-in way for the query to realize "I was supplied a YMD date, I should output dates as YMD too.".
In theory you could call SET DATEFORMAT ymd, but I mislike that because it might affect something farther down the line you don't know about.
If you want an explicit formatting/parsing style during conversion (which is almost always a good idea), you need to explicitly convert it, and supply the style:
-- 126 is hyphenated, but has extra parts if something other than date is used
CONVERT(DATE, '2017-07-28', 126)
Of course, the best option is to supply the parameter as an actual DATE type, and get output the same way, which saves you from converting back and forth to a string type, and avoids the formatting problem. This may not be available in a cases, however (like ad hoc queries).
I'm looping through LDAP data placing some data from that into an MS SQL database. Out of the 7k+ LDAP records, a few have been causing an issue when trying to place the lastlogin into the database that has a DateTime format.
The problem is the date it has, 12/31/1600 7:00:00 PM, is not correct and causes an error of
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.
I've been checking the date format before it inserts it into the database.
If Not IsDate(empInfo.lastLogon) Then
empInfo.lastLogon = Format(Now.AddYears(-1), "MM/dd/yyyy HH:MM:ss")
End If
But doesn't seem to catch the year of 1600 which seems to be causing that error above.
Is there any code I can use to detect those weird years and replace it with a random, legit date so it will place it into the database?
I think your problem is caused because what is a valid date in the code is not a valid date in the database, probably because the database can store an earliest date of 1753 something, whereas the code allows much earlier dates (such as the 1600 you cited).
Try adding a test for the year to your IF statement:
If Not IsDate(empInfo.lastLogon) OrElse empInfo.lastLogon.year < 2000 Then
empInfo.lastLogon = Format(Now.AddYears(-1), "MM/dd/yyyy HH:MM:ss")
End If
Instead of using a default of 1 year ago, you might want to use a marker value like 01/01/2000 00:00:00. This will let you easily identify ones which didn't have a "real" value. But I don't know your business rules, so YMMV.
For months use MM, but for minutes use mm.
I.e.; you should use MM/dd/yyyy HH:mm:ss instead of MM/dd/yyyy HH:MM:ss.
I hope it helps you.
I think you want something like this:
If Not IsDate(empInfo.lastLogon) OrElse DateTime.Parse(empInfo.lastLogon).Year < 2000 Then
empInfo.lastLogon = Format(Now.AddYears(-1), "MM/dd/yyyy HH:mm:ss")
End If
I have the following data:
StartDate FinishDate Details
09/10/2013 11/10/2013 xxx
14/10/2013 13/10/2014 Taking a year off
Whilst editing this data I which to check the date ranges do not overlap.
I am running an SQL query from access via ado to do this; I am putting the dates entered into database format (ie 'mm/dd/yyyy'); This is the query I've got:
SELECT Count(*)
FROM MarkerAbsence
WHERE PerID = 718 AND
('10/09/2013' BETWEEN StartDate AND FinishDate OR
'10/11/2013' BETWEEN StartDate AND FinishDate)
If the data is valid, it should return zero records; however it doesnt it returns 1 (being the second listed record above) and therefore seems to be interpreting '10/11/2013' as dd/mm/yyyy instead of mm/dd/yyyy.
Yet if I do this in SMO:
DECLARE #datevar datetime2 = '31/12/2008';
SELECT #datevar;
I get:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
While
DECLARE #datevar datetime2 = '12/31/2008';
SELECT #datevar;
returns
2008-12-31 00:00:00.0000000
So why am I having this problem and how do I fix it?
If you're running a query using MS Access, you need to delimit dates with # symbols, i.e.: #12/31/2008#. If this won't work for whatever reason, it is best to use string dates in the 'yyyy-mm-dd' format, as it will be recognized and is unambiguous.
You're probably getting this problem as MS is a US company, and the US uses mm/dd/yyyy format, so MS has defaulted much of their older software to treat dates as being in this format if at all possible, whereas you're probably in a country that uses - and have your PC's locality set to use - dd/mm/yyy format. Since not all of MS' software follows this rule, you have this problem.
The solution is to use a string date format that is unambiguous, such as: yyyy-mm-dd, mmm/dd/yyyy, or dd/mmm/yyyy (where mmm returns a three-letter month such as Dec).
You are using dd/mm/yyyy formats for your date strings. By default, without an explicit conversion, SQL is expecting date strings in the mm/dd/yyyy or yyyy-mm-dd format. So either change your strings to match one of these formats or do this:
SELECT Count(*)
FROM MarkerAbsence
WHERE PerID = 718 AND
(CONVERT(DATETIME, '10/09/2013', 103) BETWEEN StartDate AND FinishDate OR
CONVERT(DATETIME, '10/11/2013', 103) BETWEEN StartDate AND FinishDate)