2012-01-24 37 views
1

在这段MS Access Code中,我试图获取客户注册的MAX日期。首先,我必须转换日期,以便它可以使用聚合函数。不幸的是,日期列中有些区域为空。如何解决或补救错误:无效使用空值?

我收到错误由于某些记录缺失日期而无效使用空

我该如何补救,有没有解决办法?

下面是代码:

SELECT CUSTOMER.FIRST_NAME, 
    MAX(DateSerial(CInt(Left([CUSTOMER.SIGNUP_DATE],4)),CInt(Mid([CUSTOMER.SIGNUP_DATE],5,2)),CInt(Right([CUSTOMER.SIGNUP_DATE],2)))) AS SIGN_DATE, 
    (DateSerial(CInt(Left([CUSTOMER.LEAVE_DATE],4)),CInt(Mid([CUSTOMER.LEAVE_DATE],5,2)),CInt(Right([CUSTOMER.LEAVE_DATE],2)))) AS LEV_DATE 
FROM CUSTOMER 
WHERE ((DateSerial(CInt(Left([CUSTOMER.SIGNUP_DATE],4)),CInt(Mid([CUSTOMER.SIGNUP_DATE],5,2)),CInt(Right([CUSTOMER.SIGNUP_DATE],2)))) <=Date()) 
    AND ((DateSerial(CInt(Left([CUSTOMER.LEAVE_DATE],4)),CInt(Mid([CUSTOMER.LEAVE_DATE],5,2)),CInt(Right([CUSTOMER.LEAVE_DATE],2)))) =#012/31/2012#) 
GROUP BY 
    CUSTOMER.FIRST_NAME, 
    CUSTOMER.SIGNUP_DATE, 
    CUSTOMER.LEAVE_DATE; 
+2

建议:创建一个视图,说名为'CurrentCustomers'那用空'LEAVE_DATE'过滤掉客户,然后定位VIEW。但是你真的应该用实际的时间值永久替换那些与文本一样的日期列,而不是试图在飞行中这样做。 – onedaywhen

+0

谢谢!我正在考虑首先滤除空值而不是添加Aggregate,表格连接到Access,因此我必须将它们的文本值转换为日期。 – Asynchronous

+1

当你把这些名字放在括号里时,它能正常工作吗?不应该例如'[CUSTOMER.SIGNUP_DATE]'是[CUSTOMER]。[SIGNUP_DATE]'而不是?我不是一个MS Access人员,所以请原谅,如果这似乎是一个愚蠢的问题。 –

回答

1

你SIGNUP_DATE字段包含日期为这种格式的字符串: “20120131”。因此,您使用Left(),Mid()和Right()函数来分割年,月和日子字符串,将它们转换为带有CInt()的数字,最后将这些数字提供给DateSerial()。

如果只有您的日期字符串在3个部分之间包含合适的分隔符,则可以简单地将字符串提供给CDate(),例如CDate(“2012-01-31”)。所以我建议你在查询中向字符串添加分隔符并将其提供给CDate()。

这是我的简化客户表:

id SIGNUP_DATE 
1 20120130 
2 
3 20120131 

该查询转换非空SIGNUP_DATE值日期/时间值,并丢弃行,其中SIGNUP_DATE为Null(带有ID = 2的行除外)。

SELECT 
    id, 
    CDate(Left(SIGNUP_DATE,4) & "-" 
     & Mid(SIGNUP_DATE,5,2) & "-" & 
     Right(SIGNUP_DATE,2)) 
     AS SIGN_DATE 
FROM CUSTOMER 
WHERE SIGNUP_DATE Is Not Null; 

然后获得最大值很简单。

SELECT Max(q.SIGN_DATE) AS MaxOfSIGN_DATE 
FROM (
     SELECT 
      id, 
      CDate(Left(SIGNUP_DATE,4) & "-" 
       & Mid(SIGNUP_DATE,5,2) & "-" & 
       Right(SIGNUP_DATE,2)) 
       AS SIGN_DATE 
     FROM CUSTOMER 
     WHERE SIGNUP_DATE Is Not Null 
    ) AS q; 

编辑:由于没有样本数据来测试对,我只是临场发挥,并建议你试试这个查询:

SELECT 
    q.FIRST_NAME, 
    #2012/12/31# AS LEV_DATE, 
    Max(q.SIGN_DATE) AS MaxOfSIGN_DATE 
FROM (
     SELECT 
      FIRST_NAME, 
      CDate(Left(SIGNUP_DATE,4) & "-" 
       & Mid(SIGNUP_DATE,5,2) & "-" & 
       Right(SIGNUP_DATE,2)) 
       AS SIGN_DATE 
     FROM CUSTOMER 
     WHERE 
      SIGNUP_DATE Is Not Null 
      AND LEAVE_DATE = "20121231" 
    ) AS q 
GROUP BY 
    1, 
    2; 
+0

非常感谢您的宝贵意见!对于MAX函数,我不试图选择具有最高日期的CUSTOMER。我试图选择最高注册日期,如果客户多于一个。假设客户有两个日期。 2012年1月1日和2012年2月1日,然后我想要最高,你的代码给了我整个专栏中的最高日期。 – Asynchronous

+0

是的,我以这种方式呈现,因为我很容易做到。使用相同的原则并将它们应用于原始GROUP BY查询中---为每个组计算Max(),而不是仅为查询返回的完整记录集计算一次。 – HansUp

+0

是的,只有那些日期值存在时,记录才会启动。最初,MAX的整个想法是获得最高的日期。那是当我得到空错误。但是记录可以被跳过。 这是一个非常简单的查询。如果它是空的,跳过它,获得最高的日期。 是的,LEAVE_DATE可以保持这种方式,请记住,我正在创建异常情况以供学习。 – Asynchronous

相关问题