ACCESS 2007:确定多列中每行的最大值

时间:2009-10-27 13:12:52

标签: sql ms-access-2007

我有一个每个员工有多个日期列的表:

   Emp 1, Date1, Date2, Date3
   Emp 2, Date1, Date2, Date3

我想编写一个查询,向我返回每个员工可用的三个日期的最长日期。我知道我需要写一个UNION ALL查询,但我似乎无法获得语法,以便获得每个员工记录的最大值。我一直为所有员工获得相同的价值。我确定这是一个愚蠢的错误,但它让我疯了。任何帮助都将非常感激。


感谢您的快速回复!有没有办法在不使用iif语句的情况下执行此操作?如果可能的话,我想概括一下,因为还有其他几个日期字段,并且它很难弄清楚IIF逻辑。

另外,我忘了提及任何这些日期都可能为空,而IIF逻辑似乎将NULL作为最大值返回。

5 个答案:

答案 0 :(得分:1)

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

我知道这不是一个干净的解决方案 但是,当您撰写UNION时,这就是您所寻找的。

编辑:您可以使用UNION ALL代替UNION。根据上面的查询,我认为它不会对输出产生影响。

答案 1 :(得分:0)

会是这样的: (这是MSSQL2008不确定它是否可以在Acess中运行)

创建测试数据

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')

我的查询

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 

答案 2 :(得分:0)

这样的事情会起作用吗?

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

答案 3 :(得分:0)

如果您不想将解决方案限制为SQL,可以使用我的iMax()函数:

  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

我将它称为“立即Max()”,类似于IIf(),Immediate If(),因为它用于查询中的行级处理。

答案 4 :(得分:0)

哇!我觉得做一件简单太复杂了:Max(Field-Constant1,Constant2)

我的目标:根据一个字段来计算一个值,但不要让计算值小于一个常数。

两个字段表(KeyField,ValueField)上的Expample行:

1 10
2 5
3 8
4 Null

我想要一个返回的选择(当Constant1 = 6且Constant2 = 1时),我把整个数学用来澄清它(只有在最后一个之后最右边的部分是我想要的):

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

所以我只想要(当Constant1 = 6且Constant2 = 1时),以防它不够清晰:

1 4
2 1
3 1
4 Null

小心那个Null。

我真的想要一些非常复杂的东西,但解决这个问题我能够解决我想要的复杂问题。

可以恢复为: -Return Null如果value为Null或者不是所用数学运算符的有效值(不是总是只有 - 或者+等) - 如果可以进行数学运算,则返回计算值,但仅限于一个范围(不小于一个值且不大于另一个值)。

如果我在伪代码上这样做,那就是:

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;

以防万一有人说数据库没有规范化:我想对一个字段做一些数学运算,然后将结果限制在一个范围内;所以最小的样本数据库只有一个表只有两个字段(唯一的键字段,数据字段),这是不可能完全标准化的;我不是在谈论连续某些字段的最大值,也不是关于字段上的完整表格的最大值(聚合函数),只是我想将一个下限和一个上限设置为计算值,但是当这样的值时考虑为Null是Null或者无法完成对这样的值的数学运算(例如Constant1 /(FieldValue-Constant2)等)。

真实样本以防万一有人在可以使用时无法获取:

表格字段:

ID (Key)
SpacePosition (DecimalData)

查询的所需结果字段:

ID as ID
Min(Max(SpacePosition-SomeSpaceLongitud,StartPosition),EndPosition) AS RangeStart
Min(Max(SpacePosition+SomeSpaceLongitud,StartPosition),EndPosition) AS RangeEnd

希望样本很清楚,希望有人可以提供帮助,比使用VBA功能更容易!

P.D。:认为这样的数学比+和 - 更复杂,并且表有很多,更多的寄存器而不是几个,在几十亿个寄存器附近考虑。 P.P.D。:硬编码这样的结果不是一个选项,因为它不是规范化的数据库,最糟糕的是,这样的范围限制是用户在运行查询时输入的值。