Question

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 to return the NULL as the maximum value.

Was it helpful?

Solution

Will something like this work?

select
  EmployeeColumn,
  iff(iif(Date1 > Date2, Date1, Date2) > Date3, iif(Date1 > Date2, Date1, Date2), Date3)
from yourTable

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top