I'm having a problem refining an SQL query within R. I'm querying an Microsoft Access database. I'm not sure if this is an SQL problem or an R problem. I use RODBC to establish a connection, then I'm trying to limit a query by just getting results from 2000-1-1 onward.
When I query the entire field, I used str() to determine the exact date type so I could create a comparison variable. So, I got something like
wholeqry <- sqlQuery(channel,
paste("select DATE, OTHERFIELD from DB", sep=""))
(testdate <- wholeqry[1,1])
str(testdate)
This returns:
"1984-11-29 EST"
POSIXct[1:1], format: "1984-11-29"
Ok, so I format a variable so I can compare it to this:
start <- as.POSIXct(strptime("2000-01-01", format="%Y-%m-%d"), tz = "EST")
Then I check to see if they are indeed comparable with logic operators:
testdate < start
start < testdate
The results, as expected:
TRUE
FALSE
Ok, now I feel like I'm ready to do my query. I use paste() to pass start as a variable in the sql statement:
qry <- sqlQuery(channel,
paste("select DATE, OTHERFIELD from DB where DATE >=", start, sep=""))
But, when I check qry, it's the whole field minus two entries. The really confusing part to me is if I check the same entry in my new qry, I get the same date, and can compare it to my start variable, and still get the correct logic results. That is:
(testdate <- qry[1,1])
testdate < start
start < testdate
Gives the results:
"1984-11-29 EST"
TRUE
FALSE
So, while two records were kicked out by the comparison, the rest weren't, even though if I manually compare them, they should be rejected. I considered that the format of the date field may not be uniform, as some entries have time zone EDT as opposed to EST, but if I check those entries against my start date, I still get the correct logic results.
I just had this issue and solved it the following way. Access requires dates to be surrounded by the '#' symbol. The following query should work:
qry <- sqlQuery(channel, "select DATE, OTHERFIELD from DB where DATE >= #2000-01-01#")
Related
I am vb.net newbie and working on a program which will be used as a daily-worklog. As backend I use MS ACCESS. I store the "datetime.utc.now" time in a field (type:date/time) of MS Access.
This is shown in the database like: dd.mm.yyyy hh:mm:ss
I want to see all entered items of the last 12 hours. I used many different ways, but I´m not able to fix it.
My preferred / logical (for me :-)) way to do this was:
add the parameter:
mycommand.SelectCommand.Parameters.AddWithValue("date12",OleDbType.DBTimeStamp).Value = DateTime.UtcNow.AddHours(-12)
Query the database
select * from complaints where entrydate >= #date12;
But I can't figure out why it doesn't work.
Failure message = "data types in criteria expression incompatible"
I assume the problem is the different time formats, but I'm not sure and I have no clue how I could fix it.
MS Access does not use named parameters. You use a ? for all of the placeholders in the SQL statement. You still can and should give the parameter object a name, but the value is matched to the placeholder based on position in the Parameters collection and query string rather than name.
SQL:
"select * from complaints where entrydate >= ?;"
VB:
mycommand.SelectCommand.Parameters.Add("date12",OleDbType.Date).Value = DateTime.UtcNow.AddHours(-12)
Do NOT settle for hard-coding the parameter value. What you can do is use SQL expressions to determine the date value, and avoid both parameters and string concatentation:
select * from complaints where entrydate >= DATEADD('h', -12, Now())
You can change the type to OleDbType.Date or hardcode the query:
select * from complaints where entrydate >= ( Now() - 0.5 )
Trouble inserting DateTime into Access with OleDb
As a side note, most value types are generally safe to hardcode:
"select * from complaints where entrydate >= " & DateTime.UtcNow.AddHours(-12).ToOADate()
I am having an odd issue with a select statement in SQL Server Express, hopefully someone can shed some light on why I'm experiencing this behavior as well as the right way to do it.
When I run this query it returns exactly what I would expect:
SELECT
Action, TimeOccurred, UserName, IPv4From, ShareName,
FullFilePath, NewPathName, FromServer
FROM
File_System_Profiles
WHERE
Action LIKE '%create%'
AND (TimeOccurred >= '04/27/2017')
All those entries from 4/27 and anything after that.
When I run this query it returns 0 results which is extremely odd since there are entries for 4/27 in the previous query's results:
SELECT
Action, TimeOccurred, UserName, IPv4From, ShareName,
FullFilePath, NewPathName, FromServer
FROM
File_System_Profiles
WHERE
Action LIKE '%create%'
AND (TimeOccurred = '04/27/2017')
All I removed was the > between the = and the date and I get no results. I can clearly see when I run the first query that there are results where 04/27/2017 is the date that something occurred. If the first query didn't work I would assume there was a problem with my date format of MM/DD/YYYY and what is actually in the column YYYY-MM-DD HH:MM:SS but since the first one works it seems logical that the second one should.
It is a problem of the date format. As you mentioned, you are using Date format as "YYYY-MM-DD HH:MM:SS" so you should know that the value "04/27/2017" will be taken as "04/27/2017 00:00:00" when used in the comparison.
I assume that you have no record where the value in date field is "04/27/2017 00:00:00" and that is why when you use = operator, it does not match any record. However, the operator >= picks the records where hour:minute:second part of the date exist. As an example "04/27/2017 01:10:00" is greater than "04/27/2017 00:00:00" and therefore the > operator fetches those records.
Hope it helps.
First, always use ISO standard formats for comparison. Your code should look more like this:
where Action LIKE '%create%' AND
TimeOccurred = '2017-04-27'
Nauman explained the problem, which is the time component on TimeOccurred. You can solve this in various ways. One method is to convert to date. Something like this:
where Action LIKE '%create%' AND
cast(TimeOccurred as date) = '2017-04-27'
Depending on the database, the cast() might be replaced by trunc() or date_trunc() or something else.
However, I prefer this version:
where Action LIKE '%create%' AND
TimeOccurred >= '2017-04-27' AND
TimeOccurred < '2017-04-28'
It gets to the heart of the problem. And -- better yet -- SQL optimizers can make use of an index.
I would like run a SQL in MS Access like the following:
SELECT Time, Ask, Bid
FROM AUDCAD
WHERE Time LIKE '2016.10.05'
ORDER BY ID;
However the result is nothing, The Time field data is look like the following:
2016.12.05 09:42:17.026
2016.12.05 09:42:17.387
2016.12.05 09:42:17.951
2016.12.05 09:42:18.464
...
2016.12.06 09:24:41.449
2016.12.06 09:24:41.854
2016.12.06 09:24:42.258
Therefore, I would like to extract the data day by day (this example: 2016.10.05)
Can anyone help me to solve this problem?
Lawrence
You need to check two things first...
Did your insert query work without errors .. are you sure time '2016.10.5' data exist in your DB?
Can you execute standard query to get time data and it works? Meaning can you 'SELECT FROM AUDCAD" ang get time data 2016.10.5
You must use the proper syntax for date expressions in Access SQL:
SELECT [Time], Ask, Bid
FROM AUDCAD
WHERE [Time] = #2016/10/05#
ORDER BY ID;
or, if Time has a time component:
SELECT [Time], Ask, Bid
FROM AUDCAD
WHERE Fix([Time]) = #2016/10/05#
ORDER BY ID;
However, it looks like you retrieve data from a DateTime2 field in SQL Server.
Thus, either change the data type to DateTime, or use the SQL Native Driver version 10 or 11 for your ODBC connection. If not, you will receive the date/time as text, not date/time values.
The separator for DateTime fields is #. Ex: #12/30/2016#.
I would recommend to always use the american order in VBA (m/d/y) even if the local machine is configured otherwise. It works fine that way.
Your sample query
SELECT Time, Ask, Bid
FROM AUDCAD
WHERE Time LIKE '2016.10.05'
ORDER BY ID;
uses a LIKE clause without any wildcards, so WHERE Time LIKE '2016.10.05' behaves just the same as WHERE Time = '2016.10.05'. That won't return any rows because the [Time] column always includes some characters after the date.
By default, Access uses the asterisk (*) as the "0 or more characters" wildcard, so
SELECT Time, Ask, Bid
FROM AUDCAD
WHERE Time LIKE '2016.10.05 *'
ORDER BY ID;
should work. Alternatively, you could use the ALIKE ("ANSI LIKE") keyword with the percent (%) wildcard:
SELECT Time, Ask, Bid
FROM AUDCAD
WHERE Time ALIKE '2016.10.05 %'
ORDER BY ID;
Having some issues deleting rows from a data set. They need to be deleted by a date criteria, but the variable is in e8601dt. format. One thing I noticed about the variable is that its a number type variable, but left aligned (not sure if that has relevance or not), so I attempted to substring, and some additional attempts (below)...no success -
PROC SQL;
DELETE *
FROM DATASETS.BATCH_REPORT
WHERE datepart(BATCH_DATE) > '2015-10-01'
;
QUIT;
PROC SQL;
DELETE *
FROM DATASETS.BATCH_REPORT
WHERE BATCH_DATE > '11oct2015'd
;
QUIT;
Assuming there has to be an easy way to call out a value in this format...or will I need to convert this variable to a more compliable format, then do my processing?
OK...did some research. Apparently (and some one please correct me if I am wrong)...to use the e8601dt. format, a date value needs to be multiplied by 86400, then you can apply the format. So.....dividing by 86400 brought me back to the SAS data as an integer. This did the trick :
PROC SQL;
DELETE *
FROM SETS
WHERE ID >= 20372
;
QUIT;
You're close! Date conversions are a pain between systems. The representation of the values depends on the environment configuration.
Within proc SQL, I think you have to specify oracle functions (not the SAS datepart) Looks like you've figured out that Oracle's 'DATE' datatype stores both date&time within the same value. The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight). SAS has 2 different date types: date and datetime.
I'd suggest using the oracle to_date() function to compare against a character date, i.e.
WHERE BATCH_DATE > to_date('2015-10-01','yyyy-mm-dd')
If desired, you could use the oracle to_char(BATCH_DATE,'mm-dd-yyyy') to cast the date variable to a text value and then compare on the text value. But you loose some of the comparison power.
....edited due to new info about ...ew... db2 ..... :-)
I'm way NOT a DB2 guy, but maybe something like this?
First, set the date as in: (the date passed to DB2 needs the double quotes):
CALL SYMPUT('INT_DATE',"'"||PUT(sas_date,YYMMDDD10.)||"'");
Then use in the SQL as in:
PROC SQL ;
WHERE BATCH_DATE >= &INT_DATE
https://communities.sas.com/t5/SAS-Procedures/DB2-Date9-format-To-SAS-Serial-Date/td-p/32436
I have been working on a project where I have to fetch data from MS-Access database. I am using mdb-sql tool for running sql queries into that database. But the problem occurs when I try to put where clause on a datetime column. It always throws a syntax error.
Please help me how can I use dates in where column.
I have tried using these queries -
SELECT * FROM table1 WHERE checkintime > '04/22/13 12:15:39'
SELECT * FROM table1 WHERE checkintime > #04/22/13 12:15:39#
mdb-sql displays human-readable dates in results, but requires timestamp values in queries -- calculated as the number of seconds sine 1/1/1970 (the beginning of the UNIX epoch).
So the correct query to extract all records with a date greater than 04/22/13 12:15:39 would be:
SELECT * FROM table1 WHERE checkintime > 1366650939
An easy way to calculate this from the command line is:
date --date='04/22/13 12:15:39' +"%s"
You can use
MS Access: Format Function (with Dates):
where Format([checkintime ],"yyyy-mm-dd hh:nn:ss")>='2013-04-22 12:15:39'