Sql 如何解决或纠正错误:无效使用Null?

Sql 如何解决或纠正错误:无效使用Null?,sql,ms-access-2007,Sql,Ms Access 2007,在这段MS Access代码中,我试图获得客户注册的最长日期。首先,我必须转换日期,以便它可以使用聚合函数。遗憾的是,“日期”列中有空的区域 由于某些记录缺少日期,我收到无效使用null的错误 我该怎么补救呢,有解决办法吗 代码如下: SELECT CUSTOMER.FIRST_NAME, MAX(DateSerial(CInt(Left([CUSTOMER.SIGNUP_DATE],4)),CInt(Mid([CUSTOMER.SIGNUP_DATE],5,2)),CInt(Righ

在这段MS Access代码中,我试图获得客户注册的最长日期。首先,我必须转换日期,以便它可以使用聚合函数。遗憾的是,“日期”列中有空的区域

由于某些记录缺少日期,我收到无效使用null的错误

我该怎么补救呢,有解决办法吗

代码如下:

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;
选择CUSTOMER.FIRST\u NAME,
最大(日期序列(CInt(左([CUSTOMER.SIGNUP\u DATE],4))、CInt(中([CUSTOMER.SIGNUP\u DATE],5,2))、CInt(右([CUSTOMER.SIGNUP\u DATE],2)))作为签名日期,
(日期序列(CInt(左([CUSTOMER.LEAVE\u DATE],4))、CInt(中([CUSTOMER.LEAVE\u DATE],5,2))、CInt(右([CUSTOMER.LEAVE\u DATE],2)))作为LEV\u DATE
来自客户

其中((DateSerial(CInt)(左([CUSTOMER.SIGNUP_-DATE],4))、CInt(Mid([CUSTOMER.SIGNUP_-DATE],5,2))、CInt(右([CUSTOMER.SIGNUP_-DATE],2)))您的SIGNUP_-DATE字段以字符串形式包含日期:“20120120131”。因此您使用的是Left()、Mid()和Right()函数拆分年、月和日子字符串,使用CInt()将它们转换为数字,最后将这些数字输入DateSerial()

如果只有日期字符串在这三个部分之间包含合适的分隔符,则只需将该字符串提供给CDate(),例如CDate(“2012-01-31”)。因此,我建议您在查询中向字符串添加分隔符,并将其提供给CDate()

这是我的简化客户表:

id SIGNUP_DATE
1  20120130
2 
3  20120131
此查询将非Null的SIGNUP_日期值转换为日期/时间值,并丢弃SIGNUP_日期为Null的行(id=2的行除外)

那么获取最大值就很简单了

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;

您的SIGNUP_DATE字段包含以下格式的字符串形式的日期:“20120131”。因此,您正在使用Left()、Mid()和Right()函数拆分年、月和日子字符串,并使用CInt()将其转换为数字,最后将这些数字输入DateSerial()

如果只有日期字符串在这三个部分之间包含合适的分隔符,则只需将该字符串提供给CDate(),例如CDate(“2012-01-31”)。因此,我建议您在查询中向字符串添加分隔符,并将其提供给CDate()

这是我的简化客户表:

id SIGNUP_DATE
1  20120130
2 
3  20120131
此查询将非Null的SIGNUP_日期值转换为日期/时间值,并丢弃SIGNUP_日期为Null的行(id=2的行除外)

那么获取最大值就很简单了

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;

建议:创建一个名为
CurrentCustomers
的视图,过滤掉带有空
LEAVE_DATE
的客户,然后定位该视图。但是你真的应该用实际的时间值永久性地将这些文本替换为日期列,而不是尝试在运行中这样做。谢谢!我正在考虑首先过滤掉空的t在添加聚合时,表链接到Access,因此我必须将它们的文本值转换为日期。当您将名称括在括号中时,它是否正常工作?例如,
[CUSTOMER.SIGNUP\u date]
不应该是
[CUSTOMER].[SIGNUP\u date]
取而代之的是?我不是MS Access用户,所以如果这是一个愚蠢的问题,请原谅。感谢您的输入,我确实尝试过这个问题,但出现了相同的错误。建议:创建一个名为
CurrentCustomers
的视图,过滤掉带有空
离开日期的客户,然后锁定该视图。但您确实应该永久替换这些视图使用实际时态值的文本作为日期列,而不是尝试动态执行此操作。谢谢!我正在考虑首先过滤掉空值,而不是添加聚合,这些表链接到Access,因此我必须将它们的文本值转换为日期。当您将名称括在括号中时,它是否正常工作?例如,
[客户.注册日期]
be
[客户].[注册日期]
相反?我不是MS Access用户,因此如果这是一个愚蠢的问题,请原谅。感谢您的输入,我确实尝试了,但出现了相同的错误。感谢非常有价值的输入!对于MAX功能,我不尝试选择日期最长的客户。如果客户的注册日期超过一个,我尝试选择最长的注册日期。让我们来看看假设一个客户有两个日期。2012年1月1日和2012年2月1日,那么我想要最高的日期,您的代码在整个列中为我提供了最高的日期。是的,我这样表示是因为这对我来说很容易。使用相同的原则,并将它们应用到您最初的分组查询中--compute the Max()对于您的每个组,而不是对于查询返回的完整记录集仅一次。是的,只有当这些日期值存在时,记录才会被拾取。最初,最大值的全部思想是获取最高日期。这就是我得到null错误的时候。但是记录可以被跳过。这是一个非常简单的查询。如果为null,则跳过它,获取最高值est日期。是的,离开日期可以保持这种方式,请记住,我正在创建异常情况以供学习。感谢非常有价值的输入!对于MAX功能,我不尝试选择日期最长的客户。如果客户有多个日期,我尝试选择最长的注册日期。假设客户有两个日期。2012年1月1日和2012年1月1日/2012年2月2日,我想要最高的,你的代码给了我整个列中的最高日期。是的,我这样表示是因为我很容易做到。使用相同的原则,并将它们应用到你原来的分组查询中——计算最大值()对于您的每个组,而不是对于查询返回的完整记录集仅一次。是的,只有当这些日期值存在时,记录才会被拾取。最初,最大值的全部思想是获取最高日期。当时我得到了空错误。但是可以跳过记录。这是一个非常简单的查询。如果