访问在SQL视图中给出错误但查询正确运行

时间:2014-03-16 19:36:44

标签: sql vba ms-access access-vba

我在Access中有一个查询,它从两个表中返回数据。需要过滤一个表,因为我需要返回特定日期的最新条目。

我通过从另一个查询复制SQL然后在设计视图中修改它来创建查询。当我从设计视图中保存查询并运行它时,我得到了一个三列表的预期结果,每个ShiftType为每个StaffNumber的总计。但是,当我将查询移动到我的VBA应用程序时,它会抛出一个错误。此外,当我在SQL视图中查看并修改它(添加然后删除空格)时,它会抛出错误。

查询SQL是:

SELECT DataLeave.StaffNumber, TABLE1.ShiftType, Count(TABLE1.ShiftType) AS CountOfShiftType
FROM DataLeave INNER JOIN [SELECT DataShifts.StaffNumber, ShiftType, DataShifts.ShiftDate 
FROM DataShifts 
INNER JOIN [SELECT StaffNumber, ShiftDate, MAX(ID) AS IDMAX FROM DataShifts GROUP BY DataShifts.StaffNumber,DataShifts.ShiftDate]. AS FILTER ON DataShifts.ID = FILTER.IDMAX]. AS TABLE1 ON (DataLeave.LeaveDate = TABLE1.ShiftDate) AND (DataLeave.StaffNumber = TABLE1.StaffNumber)
WHERE (((DataLeave.Active)=True) AND ((DataLeave.LeaveDate) Between #9/3/2013# And #3/15/2014#) AND ((DataLeave.StaffNumber)='2537860')) OR (((DataLeave.StaffNumber)='2524710')) OR (((DataLeave.StaffNumber)='2515610') AND ((DataLeave.LeaveTypeShort) Like '*FD'))
GROUP BY DataLeave.StaffNumber, TABLE1.ShiftType
ORDER BY DataLeave.StaffNumber;

我得到的错误是:

查询experssion中的语法错误' DataShifts.ID = FILTER.IDMAX]。 AS TABLE1 ON(DataLeave.LeaveDate = TABLE1.ShiftDate)'

我设计了另一个使用IN工作的查询,但它非常慢,所以我想让它工作但到目前为止没有多少调整工作。

VBA代码是:

q = "SELECT DataLeave.StaffNumber, TABLE1.ShiftType, Count(TABLE1.ShiftType) AS CountOfShiftType "
q = q + "FROM DataLeave INNER JOIN [SELECT DataShifts.StaffNumber, ShiftType, DataShifts.ShiftDate "
q = q + "FROM DataShifts "
q = q + "INNER JOIN [SELECT StaffNumber, ShiftDate, MAX(ID) AS IDMAX FROM DataShifts GROUP BY DataShifts.StaffNumber,DataShifts.ShiftDate]. AS FILTER ON DataShifts.ID = FILTER.IDMAX]. AS TABLE1 ON (DataLeave.LeaveDate = TABLE1.ShiftDate) AND (DataLeave.StaffNumber = TABLE1.StaffNumber) "
q = q + "WHERE (((DataLeave.Active)=True) AND ((DataLeave.LeaveDate) Between #9/3/2013# And #3/15/2014#) AND ((DataLeave.StaffNumber)='2537860')) OR (((DataLeave.StaffNumber)='2524710')) OR (((DataLeave.StaffNumber)='2515610') AND ((DataLeave.LeaveTypeShort) Like '*FD')) "
q = q + "GROUP BY DataLeave.StaffNumber, TABLE1.ShiftType "
q = q + "ORDER BY DataLeave.StaffNumber;"

Set Rs = Db.OpenRecordset(q)

使用DAO

2 个答案:

答案 0 :(得分:3)

Access SQL接受2种样式的子查询包围:

  1. [statement]. AS alias
  2. (statement) AS alias
  3. 要么可以工作,但是当子查询语句包含方括号时,第一个表单可能会中断。由于您的第一个子查询包含另外一对方括号中包含的另一个子查询,我认为这可能是问题的原因。

    此外,您还有一个reserved wordFILTER作为别名。这可能会在以后产生另一个问题。

    我建议您将此SQL保存为新的Access查询 qryFilter

    SELECT
        DataShifts.StaffNumber,
        DataShifts.ShiftDate,
        MAX(DataShifts.ID) AS IDMAX
    FROM DataShifts
    GROUP BY
        DataShifts.StaffNumber,
        DataShifts.ShiftDate
    

    然后您可以修改主查询以使用 qryFilter 而不是子查询语句。

    SELECT
        dl.StaffNumber,
        t1.ShiftType,
        Count(t1.ShiftType) AS CountOfShiftType
    FROM
        DataLeave AS dl
        INNER JOIN
            (
                SELECT
                    ds.StaffNumber,
                    ds.ShiftType,
                    ds.ShiftDate 
                FROM
                    DataShifts AS ds
                    INNER JOIN qryFilter AS fltr
                    ON ds.ID = fltr.IDMAX
            ) AS t1
        ON
                (dl.LeaveDate = t1.ShiftDate)
            AND (dl.StaffNumber = t1.StaffNumber)
    WHERE
            dl.Active=True
        AND dl.LeaveDate Between #9/3/2013# And #3/15/2014#
        AND dl.StaffNumber IN ('2537860', '2524710', '2515610')
        AND dl.LeaveTypeShort Like '*FD'
    GROUP BY
        dl.StaffNumber,
        t1.ShiftType
    ORDER BY dl.StaffNumber;
    

    注意:

    1. 我忘记了WHERE子句逻辑,所以如果我弄错了你可能需要解决这个问题。
    2. 我使用第二种样式括号来表示子查询。如果您从Access 2003修改查询设计器中的查询,它可能(可能会)将它们切换到方括号。但是,因为那时只有一对方括号,所以不应该破坏查询。
    3. 最后,如果在每个子查询语句周围使用括号而不是方括号,则可以使原始语句有效。然后,每次Access 2003查询设计器切换到方括号时,请确保切换回括号。 (小心!)

答案 1 :(得分:0)

最后将是分号......

尝试在“VBA版本”中删除它。

q = "SELECT DataLeave.StaffNumber, TABLE1.ShiftType, Count(TABLE1.ShiftType) AS CountOfShiftType "
q = q + "FROM DataLeave INNER JOIN [SELECT DataShifts.StaffNumber, ShiftType, DataShifts.ShiftDate "
q = q + "FROM DataShifts "
q = q + "INNER JOIN [SELECT StaffNumber, ShiftDate, MAX(ID) AS IDMAX FROM DataShifts GROUP BY DataShifts.StaffNumber,DataShifts.ShiftDate]. AS FILTER ON DataShifts.ID = FILTER.IDMAX]. AS TABLE1 ON (DataLeave.LeaveDate = TABLE1.ShiftDate) AND (DataLeave.StaffNumber = TABLE1.StaffNumber) "
q = q + "WHERE (((DataLeave.Active)=True) AND ((DataLeave.LeaveDate) Between #9/3/2013# And #3/15/2014#) AND ((DataLeave.StaffNumber)='2537860')) OR (((DataLeave.StaffNumber)='2524710')) OR (((DataLeave.StaffNumber)='2515610') AND ((DataLeave.LeaveTypeShort) Like '*FD')) "
q = q + "GROUP BY DataLeave.StaffNumber, TABLE1.ShiftType "
q = q + "ORDER BY DataLeave.StaffNumber"