Extract partial data from a column using SQL (and maybe regex) - sql

I'm working with SQL in MS Access. One of the columns that I import from Excel has date and time in an odd format as below:
Jan 12 2021 07:55:14 AM PST
MS Access doesn't recognize this as date and time so doesn't convert it as such. I'm trying to automate some steps so don't want the user to manually delimit this column in excel and convert to DD-MM-YYYY format.
I just need to extract the dates which are almost always 11 characters in length. However, as I'm new to this, I am unable to parse it as such and the existing posts don't help much (or maybe I can't understand).

Assuming value always ends with " PST" (or any 3 characters following a space), consider:
CDate(Left([fieldname], InStrRev([fieldname], " ")-1))
That returns a valid date/time. Formatting can be applied to extract only m/d/y parts. Be aware, Format function returns a string, not a true date.
Format(Left([fieldname], InStrRev([fieldname], " ")-1), "mm/dd/yyyy")

Related

Will different Windows Time settings mess a WHERE SQL Date statement in ACCESS?

I know that ACCESS's time format depends on your Windows time settings. I use ISO-8601 format (YYYYMMDD) so that I can get away with SQL WHERE statements like this one:
WHERE dates > #2020/02/15#
AND dates < #2021/01/30#
If I run the code from above in another computer, whose Windows time settings are for example DDMMYYYY, will the SQL statement no longer work? I could simply do something like this to solve that problem (will it though?):
WHERE dates BETWEEN Format(date1, "\#YYYY\/MM\/DD\#") AND Format(date2, "#YYYY\/MM\/DD\#")
EDIT: Time format has beign changed as pointed out by #Gustav. The question remains; will the first WHERE Statement no longer work on different Windows time settings? Will the second correct the problem?
In Access SQL, use octothorpes:
WHERE dates > #2020/02/15#
AND dates < #2021/01/30#
WHERE dates BETWEEN Format(date1, "\#YYYY\/MM\/DD\#") AND Format(date2, "#YYYY\/MM\/DD\#")
Nope, Windows time settings will mess with a lot of things, but not with ordering or comparisons with dates.
As long as the field is defined as a date (so with octothorpes, like Gustav said), the 2nd of February 2021 will be less the 11th of February 2021, even though that wouldn't be the case if you cast them to a string first.
Always try to keep columns as they are when filtering, so if dates is actually a date column (and not a formatted string), just use WHERE dates BETWEEN #2020/02/15# AND #2021/01/30#, no formats, no funky stuff. And note that especially when trying to keep your application working in all locales, it's important to avoid casting dates to strings, which can happen if you compare a date with a formatted string.

Dates imported from excel documents were stored as integers

Dates entered in the "short date" format in Excel were imported differently into OpenRefine. For example, 8/30/2019 in Excel became Fri Aug 30 00:00:00 EDT 2019 in OpenRefine. I would like to get them back to a short date (mm/dd/yyyy) or even a string (mmddyyyy) format, with no day of week, time, or time zone data retained. I've been trying to transform them but can't figure out the grel code.
The toString() function takes an optional format string that you can use for this. You can use value.toString('M/d/y') (or toString(value,'M/d/y'))to get a string in the format of your first example. Note, however, that once you convert it to a string you'll lose the ability to use any of the date related functions like calculating how far apart two dates are.

vba access Dlookup with dates in dd/mm/yyyy forma

I'm trying to get a value using a DlookUp, the problem is access formats my dd/mm/yyyy into mm/dd/yyyy despite using the Format function.
muestraAguasDatos = Nz(DLookup("[name]", "samples", "[location] = '" & location & "' AND ([name] LIKE
'*ACRT*' OR [nombre] LIKE '*CAWQ*') AND [sample_date] = #" & Format(sampleDate, "dd/mm/yyyy") & "#"))
This DLookup works when day value are > 12 but when it's lower and despite having the format it still format it to mm/dd/yyyy
Can you help me solving this issue please?
There are so many misunderstanding with MS Access date fields for non-US residents.
The basic rule is :
Whenever you specify a hardcoded date literal using #the date# notation, in
either :
an SQL query
a query filter criteria
in VBA
in a Dlookup() like you do
You should ALWAYS use the US date format : MM/DD/YYYY, or the ISO format YYYY/MM/DD
The confusion among Access beginners, comes from several things :
In the interfaces, by default, MS Access does an implicit conversion of the dates in the format that is defined on Windows Regional and Language Options setting of the computer. So non-US residents might have the impression that dates are always stored by default in the DD/MM/YYYY format, but that cake is a lie. Dates are stored as numbers, and it is just the display format that changes and is adapted following the computer settings.
In some cases, when you code date literals with #the date# in VBA or a Query, using DD/MM/YYYY format, it just works fine. The reason is date there's a check date algorithm in MS Office that validates a date and modify it to the right format in certain circumstances:
When your date begins by the year, MS Access is smart enough to detect it and it will then consider that your date is enterred in YYYY-MM-DD and do an implicit convertion to MM/DD/YYYY.
If the month part is higher than 12 and lower then 31, then MS Access will understand that this is in fact a DAY, and that you hardcoded the month at the other place. So for instance if you introduce 15th of September like this : #15/09/2019# it will implicitly be transformed in #09/15/2019#. However if you enters the 11th September like this #11/09/2019#, then Access will process it as 09th November !!!
Personal opinion, I have always found this last behavior plain stupid, because it may introduces a lot of troubles on applications of people not acquainted by that mechanism, and that tracking where the problems comes can be very tedious. It's sneaky, it should not be there. Much better to raise an error if the format is wrong.

use Datetime to do a query in SQL database

I need to retrieve a tuple from the database that have a DateTime as a primary key, the problem i'm having is that it's only working with Datetime's that have the time before midday, otherside it fails to retrieve anything, here is the code:
string fecha = "22-11-2016 15:56:50";
DateTime myDate = DateTime.ParseExact(fecha, "dd-MM-yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
modelo.solicitud = BD.Solicitud.Find(myDate);
in resume I get a null in modelo.solicitud
if the string fecha is like "01-01-2017 09:00:00" (before midday) it success to retrieve from database, but if it's like "01-01-2017 16:00:30" will fail to retrieve a thing..
Any help of recomendation will be appreciated..
Regardless of the DBMS you are using, fields (columns) that are defined as DATETIME are stored as a binary value. What you see is a generated string representation of the binary value according to either the defaults defined for the DB or a specific format you define for presentation.
You can try setting the default datetime format to something like 'yyyy-mm-dd hh24:mm:ss' (hh24 is Oracle's way to say that you want the hours part to be in the 0-23 range; you will need to check how this is done in your case).
This format also removes ambiguities related to the American/European way of writing dates (i.e. mm/dd/yyyy in the US vs. mm/dd/yyyy in Europe, such that 3/4/16 would mean March the 4th 2016 in the US but April the 3rd 2016 in Europe).
Last, the Spanish word resume has a different meaning than in English (you would normally say summary).
Hope this is clear for you now.

ADO MAX Time query

I'm using an ADO\ACE.OLEDB query to access data in an excel sheet. One of the columns in this sheet is a time stamp in the 00:00:00 format.
My select max query for this column works OK but it returns the wrong "max" time. For example, if I have the following time stamps:
08:15:00
09:45:00
10:00:00
The SELECT MAX query will return 09:45:00, and ignore any subsequent timestamps. If I go to the queried sheet, and convert all the cells in that column to "Time" using text-to-columns, the query will then return the correct value of 10:00:00.
The timestamp that is recorded in the excel sheet is updated very often by many different people throughout the day using their own ADO Update\Insert query so it's not feasible for me to open the sheet and convert the cells to the correct type manually. The update\insert queries have the cell types set to General.
So my question is this.
Is there a way to either
A) Specify the data type in the update\insert into ADO query so the cell has the correct data type? Or
B) Force the SELECT MAX query to interpret the column as a timevalue rather than text?
If not any suggestions on how to procede?
EDIT: I looked closer at the excel sheet i'm querying. I noticed that each cell has a singlequote preceding it. I think if I can get that removed when entries are recorded excel might properly format the cell as time.
Here is a basic example of wha is being used to write entries to the sheet.
Update [Sheet1$] Set StopTime='09:45:00' WHERE Date= '3/12/2014' AND StartTime='9:30:00'
Can this be rewritten so a single quote ins't included? Note there is no end quote.
The single quote at the beginning of a cell in Excel forces Excel to interpret the cell value as text. The single quote is probably being inserted because the update statement uses single quotes, which indicate strings. You may be able to use ## delimiters instead, which specifically indicate date/time values (I say "may" because I haven't tested this). For example:
UPDATE [Sheet1$]
SET StopTime = #09:45:00#
WHERE [...]
On the other side, you can force a column to be interpreted as a date/time by using the CDate function:
SELECT MAX(CDate(StopTime)) AS MaxTime
FROM [Sheet1$]
You just have to be careful in this case about values that cannot be converted to a valid time, which will cause the query to error out.
I didn't even realise this but the examples I gave were flawed. What is logged does NOT include a leading zero. Since I'm using a 24hr time I was able to correct this issue by writing a leading zero into the time that gets recorded.
Basically it's an, if LEN(time)=7 then time = 0 & time.
This appears to be working so far.