我有一个数据库,该数据库可跟踪组织零件清单中的贷款和投资回收期。它们是单独的表DiversionT和PaybackT。我也有包含客户和零件信息的表CustomerT和PartsT。我有一个查询(包含两个子查询),其目标是从表单中获取客户和零件,并让一个子查询计算给定零件和给定客户的贷款总和。
FROM PartsT INNER JOIN (CustomerT INNER JOIN DiversionT ON CustomerT.CustomerID = DiversionT.CustomerID) ON PartsT.PartID = DiversionT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]));
另一个子查询求和相同客户和零件的投资回报。
SELECT CustomerT.CustomerProgram,PartsT.PartID,Sum(PaybackT.PayAmountParts) AS SumOfPayAmountParts
FROM PartsT INNER JOIN (CustomerT INNER JOIN PaybackT ON CustomerT.CustomerID = PaybackT.CustomerID) ON PartsT.PartID = PaybackT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]));
然后将这些结果进行求差,以得到所欠的余额,然后通过Excel呈现以进行导出:
FROM SinglePartSumQ, CustomerT, SinglePartPaybackSumQ INNER JOIN PartsT ON SinglePartPaybackSumQ.PartID = PartsT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID, PartsT.IndiaUID, PartsT.NSN, PartsT.PartName, SinglePartSumQ.SumOfRcvdQTY, SinglePartPaybackSumQ.SumOfPayAmountParts
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]))
ORDER BY CustomerT.CustomerProgram;
对于同时位于DiversionT和PaybackT中的项目,查询工作正常,但是在可能未发生任何回收的情况下,我希望第二个子查询返回客户,零件ID和总和的0。现在,第二个子查询返回空白,因此最终的差异查询不起作用。
我已经尝试在我的投资回报总额查询中使用ISNULL函数,其中对于客户和零件,如果为null,我希望它返回名称和零件ID,然后当总和始终为null时,则返回0,这样差分操作将使用0。
我已经尝试了以下ISNULL的实现来实现投资回报总额查询:
SELECT ISNULL(CustomerT.CustomerProgram,CustomerT.CustomerProgram), ISNULL(PartsT.PartID,PartsT.PartID), ISNULL(Sum(PaybackT.PayAmountParts),0) AS SumOfPayAmountParts
FROM PartsT INNER JOIN (CustomerT INNER JOIN PaybackT ON CustomerT.CustomerID = PaybackT.CustomerID) ON PartsT.PartID = PaybackT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]));
但是我遇到运行时错误'3326':此记录集不可更新。当我尝试调试时,将带我进入以下格式的VBA代码:
Option Compare Database
Private Sub AllPartSearch_Click()
End Sub
Private Sub OnePartOneCust_Click()
Dim getFolder As Object
Dim sLoc As String
Dim fileN As String
DoCmd.OpenQuery "SinglePartSumQ"
DoCmd.OpenQuery "SinglePartPaybackSumQ"
DoCmd.OpenQuery "OneCustOnePartQ"
Set getFolder = Application.FileDialog(msoFileDialogFolderPicker)
With getFolder
.AllowMultiSelect = False
fileN = Forms!PartsSearchF!FileName
If .Show = True Then
sLoc = getFolder.SelectedItems(1) & "\"
End If
End With
DoCmd.TransferSpreadsheet acExport, , "OneCustOnePartQ", sLoc & fileN & ".xlsx", True
End Sub
Private Sub PartSearch_Click()
End Sub
调试器将第二个DoCmD.OpenQuery
语句标记为投资回报查询,当我运行调试器时,得到运行时错误'3075':查询表达式'ISNULL(CustomerT.CustomerProgram)中的函数使用的参数数量错误,CustomerT.CustomerProgram'。
首先可以做我想做的事吗?第二,我的ISNULL实现有什么问题?
更新:我已将ISNULL更改为NZ。当我使用在PaybackT中没有任何条目的零件时,投资回报查询返回三列Expr1,Expr2,SumofPayAmountParts,其中没有任何内容。另外,无论PaybackT中的状态如何,查询都会打开一个参数窗口以查找输入,但是它应该从所需的表单中获取所有内容,例如NZ
或ISNULL
不在时?这是我现在用于回报查询的代码:
SELECT Nz(CustomerT.CustomerProgram,CustomerT.CustomerProgram) AS Expr1, Nz(PartsT.PartID,PartsT.PartID) AS Expr2, Nz(Sum(PaybackT.PayAmountParts),0) AS SumOfPayAmountParts
FROM PartsT INNER JOIN (CustomerT INNER JOIN PaybackT ON CustomerT.CustomerID = PaybackT.CustomerID) ON PartsT.PartID = PaybackT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]));
这是差异查询的代码;
SELECT NZ(CustomerT.CustomerProgram,CustomerT.CustomerProgram), NZ(PartsT.PartID,PartsT.PartID),NZ(PartsT.IndiaUID, PartsT.IndiaUID),NZ(PartsT.NSN,PartsT.NSN), NZ(PartsT.PartName,PartsT.PartName), NZ(SinglePartSumQ.SumOfRcvdQTY,SinglePartSumQ.SumOfRcvdQTY), NZ(SinglePartPaybackSumQ.SumOfPayAmountParts),SinglePartPaybackSumQ.SumOfPayAmountParts, SinglePartSumQ.SumOfRcvdQTY-SinglePartPaybackSumQ.SumOfPayAmountParts AS BalanceOwed
FROM SinglePartSumQ, CustomerT, SinglePartPaybackSumQ INNER JOIN PartsT ON SinglePartPaybackSumQ.PartID = PartsT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID, PartsT.IndiaUID, PartsT.NSN, PartsT.PartName, SinglePartSumQ.SumOfRcvdQTY, SinglePartPaybackSumQ.SumOfPayAmountParts
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]))
ORDER BY CustomerT.CustomerProgram;
更新2:基于一些费用返还,我已经更新了我的代码,所有列标题现在都显示在所有三个查询中,但是投资回收期和差异查询仍然显示为空白。
这里是转移总和查询:
SELECT CustomerT.CustomerProgram, PartsT.PartID, Sum(Nz(DiversionT.RcvdQTY,0)) AS SumOfRcvdQTY
FROM PartsT INNER JOIN (CustomerT INNER JOIN DiversionT ON CustomerT.CustomerID = DiversionT.CustomerID) ON PartsT.PartID = DiversionT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]));
回收期总和查询
SELECT CustomerT.CustomerProgram, PartsT.PartID, Sum(NZ((PaybackT.PayAmountParts),0)) AS SumOfPayAmountParts
FROM PartsT INNER JOIN (CustomerT INNER JOIN PaybackT ON CustomerT.CustomerID = PaybackT.CustomerID) ON PartsT.PartID = PaybackT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]));
和差异查询
SELECT CustomerT.CustomerProgram, PartsT.PartID,PartsT.IndiaUID,PartsT.NSN,PartsT.PartName,SinglePartSumQ.SumOfRcvdQTY, SinglePartPaybackSumQ.SumOfPayAmountParts, NZ(SinglePartSumQ.SumOfRcvdQTY,0)-NZ(SinglePartPaybackSumQ.SumOfPayAmountParts,0) AS BalanceOwed
FROM SinglePartSumQ, CustomerT, SinglePartPaybackSumQ INNER JOIN PartsT ON SinglePartPaybackSumQ.PartID = PartsT.PartID
GROUP BY CustomerT.CustomerProgram, PartsT.PartID, PartsT.IndiaUID, PartsT.NSN, PartsT.PartName, SinglePartSumQ.SumOfRcvdQTY, SinglePartPaybackSumQ.SumOfPayAmountParts
HAVING (((CustomerT.CustomerProgram)=[Forms]![PartsSearchF]![CustomerSearch]) AND ((PartsT.PartID)=[Forms]![PartsSearchF]![PartSearch]))
ORDER BY CustomerT.CustomerProgram;
我感觉问题在于Access生成的inner join
语句以及它如何寻找比较。由于Diversion表永远不会有空条件,因为如果我基于Diversion的差异表中显示的内容,就不会查看是否未借出零件。即在差异查询中修复此行(我只是不知道如何成为SQL新手):FROM SinglePartSumQ, CustomerT, SinglePartPaybackSumQ INNER JOIN PartsT ON SinglePartPaybackSumQ.PartID = PartsT.PartID