I'm trying to extract the numerical hour value from a column that contains time formatted as DateTime. For example, here are a couple of records from that column:
Time Aired
4:20:00 PM
12:51:00 PM
3:17:00 PM
3:24:00 PM
From this column I'm trying to extract 4, 12, 3, 3, etc. The DATEPART function appears to be a good option for this. However, when I try to use that function as shown below I'm prompted to enter a parameter for Hour. This leads me to believe I'm implementing DATEPART incorrectly. Can someone spot what the problem may be? Could the problem be that my datetime formatted column contains time values only?
SELECT DATEPART(hour, [Time Aired]) AS Foo
FROM DRTV_CentralOnly
WHERE [Time Aired] <> null;
This documentation shows that the interval part (hours) should be enclosed in quotes and it should be h, not hours; therefore, try this:
SELECT DATEPART("h", [Time Aired]) AS Foo
FROM DRTV_CentralOnly
WHERE [Time Aired] is not null;
My other question would be, aren't you supposed to write WHERE [Time Aired] is not null ?
You can use HOUR function instead of DATEPART.It gives hour numbers irrespective of AM/PM
SELECT HOUR([Time Aired]) AS Foo
FROM DRTV_CentralOnly
WHERE [Time Aired] <> null;
There are several ways you can extract only the number of hours from an MS Access Date value in a query expression a few ways.
Here are some of the methods:
DatePart("h", [yourFieldName]) 'returns a variant (Integer)
Format([yourFieldName],"h") 'returns a variant (String)
Hour([yourFieldName]) 'returns a variant (Integer)
In Access, I prefer the last method because it's short and clear.
Based on the question, I suspect you were looking at the documentation for the SQL Server DATEPART function which has some subtle differences.
Don't make the mistake of thinking that SQL is all the same. There are similarities but the syntax is not always interchangeable, especially when talking about MS Access. When searching for answers about Access, I always include mc access as part of my Google search query, and even still, when you find a potential answer, confirm that the page you're looking at was actually written for Access.
Your NULL problem
There's something you didn't ask for help for, but that you need help with! :) Indeed this is an old post, so you must have either figured out your mistake, or you're still stuck on it, or the company has been putting out incorrect reports for the last 6 years.
[myFieldName] Is Not Null is not the same as [myFieldName] <> Null.
The short explanation is that Null is not a value. Null can things around it. It's not a zero, it's not a '' empty string, and it's not a ZLS (zero-length-string).
The way you were using the <> NULL criteria it's likely your query was returning no records because of the incorrect syntax.
Examples:
For example: what result do you think this simple equation will produce?
(Null+2)*3
...if you said 6, you're wrong!
The result is: NULL. Basically, anything that touches NULL becomes NULL.
One more example. Run this in VBA:
If Null = Null Then MsgBox "Null equals Null." Else MsgBox "Null does NOT equal Null."
...you might not get the answer you'd expect!
For accuracy, all operators must be used the way they were intended, including the use of Is and Is Not operators with the NULL Statement.
More Information:
Office Support : DatePart Function (Access Query or VBA)
Office Support : Format Function (Access Query or VBA)
Office Support : Hour Function (Access Query or VBA)
Allen Browne : Common Errors with Null
Red-Gate : How to get NULLs Terribly Wrong in SQL Server
TechRepublic : 10 tricks for handling Null values in Microsoft Access
Wikipedia : Null (mathematics)
MSDN: Is Operator
Preparing for Unexpected Data:
This is actually only barely related, but made me LMAO because I never woudl have thought to prepare for this, and I figured I ought to share:
...which, in return, reminds me of that annoying little kid, Bobby Tables.
Related
This Round statement is producing an error when the IIf condition is false, it works when the IIf condition is true.
I have very limited experience with SQL. I inherited this Access DB, which I'm trying to tweak, from a colleague who has retired, so I've been taking shots in the dark at troubleshooting and piecing together syntax.
This is the Round statement I'm trying to get to work:
Round(IIf([Manual] is Not Null,[Manual]/180,[MemberDays]/180),3) AS [%ADM]
Troubleshooting edit:
Round(IIf([Manual] is Not Null,180/180,100/180),3) AS [%ADM]
The Manual field is created by this statement (not sure if relevant, but figured I'd include):
IIf(([2-billing-Prep Export]!wth_date) Is Not Null,[MemberDays]-[Session Cum]+1,"")) AS Manual
Expected results: %ADM will be populated with Manual/180 to 3 dec pts if Manual is not null. If Manual is null, %ADM will be populated with MemberDays/180 to 3 dec pts.
Actual results: The statement works if Manual is not null, but %ADM is populated with #ERROR when Manual is null. Google tells me this is because one of the fields in the calculation is null...but MemberDays is never null.
Results from troubleshooting edit: %ADM is populated as if the condition is always true, even for records where Manual is, or appears to be, null. I'm confused because before making the troubleshooting edit, the condition seemed to recognize null/non null values in Manual.
In an IIf expression, both the true-part and the false-part are evaluated, and if one of them can't be evaluated, an error is returned. In your case, you believe that Manual can be Null sometimes, but I don't think so... because in the IIf formula for Manual, you return an empty string when it should return Null. An empty string can't be divided by a number. Therefore:
Change the expression for the Manual field to
IIf(([2-billing-Prep Export]!wth_date) Is Not Null,[MemberDays]-[Session Cum]+1,Null)) AS Manual
I am working on a Attendance table in Access, where I have InTime and OutTime. These fields are of Date/Time Field.
Some records contains only Time like 11:40:00, some contain Date as well as time like 21-07-2015 11:45:00. Hence have used the below code for getting hours worked.
HrsPresent: Round(DateDiff("n",TimeValue(TimeSerial(Hour([TimeIn]),Minute([TimeIn]),Second([TimeIn]))),TimeValue(TimeSerial(Hour([TimeOut]),Minute([TimeOut]),Second([TimeOut]))))/60,2)
Using this above code, in a Column in making query gives correct Number of hours worked, but if any of the field is blank, i get #error in result.
I have tried using Nz , IsError, IsNumeric but all in Vain.
What is it that, I am doing wrong?
Is other way of getting hours worked?
You basically just need to make sure that both of the needed fields aren't blank before performing your calculation. You could do this using two IIF statements. If one field is blank then you simply assign a default value or handle it how you want.
In my example the default is zero, I have to warn you though this was done free hand and I am not super confident that my brackets line up properly. Also I am sorry that it is all on one line, I couldn't think of a logical way to break it down.
HrsPresent: IIF(Nz([TimeIn],"") = "", 0, IIF(Nz([TimeOut],"") = "", 0, Round(DateDiff("n",TimeValue(TimeSerial(Hour([TimeIn]),Minute([TimeIn]),Second([TimeIn]))),TimeValue(TimeSerial(Hour([TimeOut]),Minute([TimeOut]),Second([TimeOut]))))/60,2)))
For more information on IIF statements you can use visit here: http://www.techonthenet.com/access/functions/advanced/iif.php
It seems that a query of mine returns wrong results, and I'm not sure why. I don't yet rule out the possibility that the SQL is actually doing something else then what I expect/want it to do since I haven't used SQL for a time now.
I post it here because I'm kind a stuck with the why it returns wrong results sometimes.
The error is in the MIN(FIRM.account_recharge.X__INSDATE) (or at least the ones I noticed)
SELECT
FIRM.customer.CUSTOMER_ID,
FIRM.customer.CORPORATION,
FIRM.customer.CUSTOMER_NAME_PREFIX,
FIRM.customer.CUSTOMER_NAME,
FIRM.account.ACCOUNT_TYPE,
FIRM.account.ACCOUNT_TYPE,
FIRM.customer.LANGUAGE,
FIRM.customer.VALIDATED,
FIRM.account.X__INSDATE,
SUM(FIRM.account_recharge.GROSS_VALUE) SUM_FELTOLTESEK,
MIN(FIRM.account_recharge.X__INSDATE),
INNER JOIN FIRM.account
ON FIRM.customer.CUSTOMER_ID = FIRM.account.CUSTOMER
INNER JOIN FIRM.customer_address
ON FIRM.account.CUSTOMER = FIRM.customer_address.CUSTOMER
INNER JOIN FIRM.account_recharge
ON FIRM.account.ACCOUNT_ID = FIRM.account_recharge.ACCOUNT
GROUP BY FIRM.customer.CUSTOMER_ID,
FIRM.account.X_INSDATE,
FIRM.customer.CORPORATION,
etc,etc
HAVING MIN(FIRM.account_recharge.X__INSDATE) BETWEEN to_date('2014-JAN. -01','YYYY-MON-DD') AND to_date('2014-DEC. -31', 'YYYY-MON-DD');
This code should return information abut our customers, their sum account 'recharging'/'replenishing'/'paying in' , sorry not sure of what word to use here. and their first payment/money upload to their account in 2014. Yet sometimes the return values seems to just ignore the actual first time our client paid in money, and shows the second or third date. (my random manual check returned that around 1/10 of the time the returned values are wrong.)
A costumer of ours can have more the one account linked to him. I'm using Oracle SQL developer (4.0.0.12) please ask if you would like to know anything else about this pickle im in.
Otherwise It seems to work nicely, but if you have any other tuning tip, I would be glad to hear them.
Thank you for your help!
HAVING MIN(FIRM.account_recharge.X_INSDATE) BETWEEN '14-JAN. -01' AND '14-DEC. -31'
This is definitely incorrect. You are comparing dates. so, you must convert the string literal explicitly into a date using TO_DATE and proper format mask.
For example,
HAVING MIN(FIRM.account_recharge.X_INSDATE)
BETWEEN to_date('2014-JAN-01','YYYY-MON-DD')
AND to_date('2014-DEC-31', 'YYYY-MON-DD')
Also, do not use YY to denote the year. You don't have to re-invent the Y2K bug again. Always use YYYY format for an year. Else, if you are stuck with YY values for year, then use RR format. But, I would insist, always use YYYY format for year.
I don't have much experience so I apologize in advance for a potentially dumb question. I did not create these tables nor the queries that have been used in the past. With that said --
For the past several months I have been using a date conversion query that was given to me to update columns from an integer to a date. It used to work just fine and I swear everything is the same for my latest data extractions, but at some point the dates started getting wonky. For example, a typical date column might look like:
58222
58158
59076
58103
And the conversion query looks something like this:
IIf([D_posting]<>0,[D_posting]-18261,0)
And returns the above dates as:
05/27/2059
03/24/2059
09/27/2061
01/28/2059
Which obviously is wrong. The situation kind of reminds me of how I remember we generated random numbers in C++ (which was a long time ago), but for the life of me I can't figure out how to reverse engineer the correct subtraction factor without a reference point.
I also tried using the CDate() function instead, and it resulted in a bunch of future dates also, leading me to wonder if there's something else wrong. I work for a small physicians group so it might be something in the Electronic Health Records software, but I'd like suggestion on what I should check to make sure it's nothing that I've done.
You could create a query that uses the 'cdate' function (see below) to return the date. You can modify the code so that it subtracts the offset (maybe 18261?)
In the immediate window of VBA you can tinker with the following:
The 'cdate' will take a number and convert it to a date:
?cdate(41925)
10/13/2014
The 'cdbl' will take a date and convert to a number.
?CDbl(Date())
41926
I have an Access 2007 report that prompts for a range of dates. It is using the SQL Query:
SELECT Calls.CallID, Contacts.County, Calls.ContactID, Calls.Date, Calls.Subject, Calls.Notes, Calls.Time FROM Contacts INNER JOIN Calls ON Contacts.[ContactID] = Calls.[ContactID] WHERE (((Calls.Date) Between [From date: ] And [To date: ]));
This works for most dates but I am getting an error when using the dates 07/01/2009 and 06/14/2010.
This expression is typed incorrectly, or it is too complex to be evaluated. For example, a numeric expression may contain too many complicated elements. Try simplifying the expression by assigning parts of the expression to variables. (Error 3071)
I have confirmed that none of the Calls.Date values are null. Is there some better way to prompt the user for the date range?
The best way to get parameters from a user is with a form. You can refer to the form in the query, for example:
Between Forms!frmDates!FromDate And Forms!frmDates!ToDate
It will make life easier for you, because you can evaluate the input before running the query. It will also make life a lot easier for the user, in that you can take advantage of the calendar that attaches to date data types in Access 2007 & 2010.