ACCESS 2007: Determine maximum value per row across multiple columns
I have a table with multiple date columns per employee:
Emp 1, Date1, Date2, Date3
Emp 2, Date1, Date2, Date3
etc.
I would like to write a single query that returns to me the maximum date of the three dates available on a per-employee basis. I understand I need to write a UNION ALL query but I can't seem to get the syntax so that I get a max value per employee record. I keep getting the same value for all employees. I'm sure this is a stupid error, but it's driving me nuts. Any help would be most appreciated.
Thank you for the prompt responses! Is there a way to do this without using an iif statement? I'd like to generalize it if at all possible, since there are several other date fields and it gets really unwieldy figuring out the IIF logic.
Also, I forgot to mention that any of those dates could be empty, and the IIF logic seems 开发者_Go百科to return the NULL as the maximum value.
SELECT ID, Max(TheDate) AS MaxDate
FROM
(
SELECT ID, Date1 AS TheDate
FROM myTable
UNION
SELECT ID, Date2 AS TheDate
FROM myTable
UNION
SELECT ID, Date3 AS TheDate
FROM myTable
)
GROUP BY ID
I know that this is not a clean solution.
But this is what you are looking for when you wrote of UNION
.
EDIT: You could use UNION ALL
instead of UNION
. With above query, it will not make a difference in the output, I suppose.
Will something like this work?
select
EmployeeColumn,
iff(iif(Date1 > Date2, Date1, Date2) > Date3, iif(Date1 > Date2, Date1, Date2), Date3)
from yourTable
Would something like this do: (this was MSSQL2008 not sure if it will work in Acess)
Create Test Data
create table t1
( EmployeeId int,
Date1 datetime,
Date2 datetime,
date3 datetime)
insert into t1 values (1, '2009-10-11', '2009-04-01', '2009-12-25')
insert into t1 values (2, '2009-10-24', '2009-04-03', '2009-12-19')
My Query
select case
when date1 > date2 and DATE1 > date3 then date1
when date2 > date1 and date2 > date3 then date2
when date3 > date1 and date3 > date2 then date3
end as highest
from t1
If you don't want to restrict the solution to SQL, you could use my iMax() function:
Public Function iMax(ParamArray p()) As Variant
' Idea from Trevor Best in Usenet MessageID rib5dv45ko62adf2v0d1cot4kiu5t8mbdp@4ax.com
Dim i As Long
Dim lngUBound As Long
Dim v As Variant
v = p(LBound(p))
lngUBound = UBound(p)
For i = LBound(p) + 1 To lngUBound
If v < p(i) Then
v = p(i)
End If
Next
iMax = v
End Function
I call it "Immediate Max()" on analogy from IIf(), Immediate If(), because it's intended for row-level processing within a query.
Wow! I am seeing it is too complex to do a simple: Max(Field-Constant1,Constant2)
.
My Objective: Calulate a value depending on only one filed, but do not let calculated value be less than a constant.
Expample Rows on a two field table (KeyField, ValueField):
1 10
2 5
3 8
4 Null
I want a select that returns (when Constant1=6 and Constant2=1), i put the whole maths to clarify it (only the top most right part after the last = is what i want):
1 Max(10-6,1)=Max(4,1)=4
2 Max(5-6,1)=Max(-1,1)=1
3 Max(8-6,1)=Max(2,1)=1
4 Max(Null-6,1)=Max(Null,1)=Null
So i just want (when Constant1=6 and Constant2=1) in case it is not enough clear:
1 4
2 1
3 1
4 Null
Beware of that Null.
I really want something really more complex, but solving that i would be able to solve the complex one i want.
It can be resumed as: -Return Null if value is Null or not a valid value for the math operator used (not allways is just a - or a +, etc) -Return the calculated value if it is possible to do the math, but limited to a range (not less than a value and not bigger than another value).
If i do it on pseudo-code it would be as this:
try // try to do the maths
MyCalculatedValue=SomeMaths(FieldValue);
MyCalculatedValue=Min(Max(MyCalculatedValue,MinValue),MaxValue);
except // In case the SomeMaths can not be done (FieldValue is Null, negative square, division by zero, etc)
MyCalculatedValue=Null;
end;
return MyCalculatedValue;
Just in case someone say database is not normalized: I want to do some maths to a field, then limit the result in a range; so smallest sample database will only have one table that will only have two fields (unique key field, data field), that is imposible to not be fully normalized; i am not talking about maximun of some fields on a row, neither maximun for a full table on a field (aggregate functions), just only i want to put a lower and an upper limits to a calculated value, but considering Null when such value is Null or the maths to be done to such value can not be done (cases like Constant1/(FieldValue-Constant2), etc.).
Real sample just in case someone do not get when this can be used:
Table Fields:
ID (Key)
SpacePosition (DecimalData)
Desired result fields for the query:
ID as ID
Min(Max(SpacePosition-SomeSpaceLongitud,StartPosition),EndPosition) AS RangeStart
Min(Max(SpacePosition+SomeSpaceLongitud,StartPosition),EndPosition) AS RangeEnd
Hope sample is clear and hope someone can help, with something easier than using VBA functions!
P.D.: Think that such Maths are more complex than just + and -, and table has a lot, lot more registers than just a few, think on near some billions of registers. P.P.D.: It is not an option to hard code such results, since it would be no normalized database and worst, such range limits are values typed by user when running the query.
精彩评论