访问& SQL Server:自日期以来的使用次数聚合问题 - 新的报告问题(已解决的聚合问题)

发布于 2024-11-29 02:16:35 字数 4026 浏览 6 评论 0原文

背景:
我一直在努力简化在我的程序中运行报告所涉及的工作。最近,我必须提供已使用仪器的工作编号列表以及成本/效益分析项目列表。主要是为了了解仪器自上次维修/校准以来以及上次有人使用它的频率。我希望将其集成到有助于生成报告的查询中 - 但我一直在使用次数方面遇到障碍 - 因为我希望该聚合基于仪器上次校准的日期(基于字段的日期)在同一查询中)。我可以让它给我系统总的使用次数 - 但它不会接受我希望它只计算自上次校准以来使用的次数的限制

问题:
尝试在我的报告中添加一个聚合函数来计算使用次数,因为该项目的校准要么出现不期望的结果,要么出现可怕的“聚合丢失”错误(不记得确切的警告)。

-- 编辑添加 8/12/2011 @ 16:09 --

对于从未使用过且被此查询排除的工具,发现了使用 Max 聚合的另一个问题。

详细信息:

这是迄今为止有效的查询:

SELECT
  dbo_tblPOGaugeDetail.intGagePOID,
  dbo_tblPOGaugeDetail.strGageDetailID,
  dbo_Gage_Master.Description,
  dbo_Gage_Master.Manufacturer,
  dbo_Gage_Master.Model_No,
  dbo_Gage_Master.Gage_SN,
  dbo_Gage_Master.Unit_of_Meas,
  dbo_Gage_Master.User_Defined,
  dbo_Gage_Master.Calibration_Frequency,
  dbo_Gage_Master.Calibration_Frequency_UOM,
  dbo_tblPOGaugeDetail.bolGageLeavePriceBlank,
  dbo_tblPOGaugeDetail.intGageCost,
  dbo_Gage_Master.Last_Calibration_Date,
  dbo_Gage_Master.Next_Due_Date,
  dbo_tblPOGaugeDetail.bolGageEvaluate,
  dbo_tblPOGaugeDetail.bolGageExpedite,
  dbo_tblPOGaugeDetail.bolGageAccredited,
  dbo_tblPOGaugeDetail.bolGageCalibrate,
  dbo_tblPOGaugeDetail.bolGageRepair,
  dbo_tblPOGaugeDetail.bolGageReturned,
  dbo_tblPOGaugeDetail.bolGageBER,
  dbo_tblPOGaugeDetail.intTurnaroundDaysOut,
  qryRCEquipmentLastUse.MaxOfdatDateEntered
FROM (dbo_tblPOGaugeDetail
  INNER JOIN dbo_Gage_Master ON dbo_tblPOGaugeDetail.strGageDetailID = dbo_Gage_Master.Gage_ID)
  INNER JOIN qryRCEquipmentLastUse ON dbo_Gage_Master.Gage_ID = qryRCEquipmentLastUse.Gage_ID
ORDER BY dbo_tblPOGaugeDetail.strGageDetailID;

但我似乎无法使用以下字段从 tblGageActivity 聚合使用计数(制作 Count(strCustomerJobNum)):

strGageID
strCustomerJobNum
datDateEntered
datTimeEntered

我尝试在之前列出的查询中添加一个字段以执行 Count(strCustomerJobNum),其中 datDateEntered 与调用查询中的 Last_Calibration_Date 匹配 - 但我得到了“缺少聚合”错误。如果我忽略这个条件 - 它会运行 - 但只会列出所有发出的仪器,前提是它的使用次数至少为一(遗憾的是,这根本不是我想要的)。

我还想确保,如果我应该得到零使用计数 - 我将得到零返回,而不是我的预期记录减去空结果。

我希望有人能告诉我哪里出了问题——每当我想生成此报告时,我想节省目前在另一个程序中运行活动报告所花费的时间。预先感谢,如果您需要我发布更多信息,请告诉我。

-- 编辑添加 08/15/2011 @ 14:41 --

我设法通过创建“纯”第一步查询来解决 Max() 聚合问题,以获取具有最新日期作为 qryRCEquipmentUsed 的所有仪器的列表。

qryRCEquipmentLastUse

SELECT dbo.tblGageActivity.strGageID, Max(dbo.tblGageActivity.datDateEntered) AS datLastDateUsed
FROM dbo.tblGageActivity
GROUP BY dbo.tblGageActivity.strGageID;

然后,我创建了一个“纯”列表,列出了完全没有使用过的所有仪器,作为名为 qryRCEquipmentNeverUsed 的查询。

qryRCEquipmentNeverUsed

SELECT dbo_Gage_Master.Gage_ID, NULL AS datLastDateUsed
FROM dbo_Gage_Master LEFT JOIN dbo_tblGageActivity ON dbo_Gage_Master.Gage_ID = dbo_tblGageActivity.strGageID
WHERE (((dbo_tblGageActivity.strGageID) Is Null));

注意:插入 NULL 是为了使第三个组合 UNION 查询不会因从表中检索的字段数量不匹配而失败。

最后,我创建了一个名为 qryCombinedUseEquipment 的 UNION 查询,将两者组合成一个列表:

qryCombinedUseEquipment

SELECT *
FROM qryRCEquipmentLastUse
UNION SELECT *
FROM qryRCEquipmentNeverUsed;

使用最后一个联合查询将上次使用日期提供给父查询在数据表视图中工作,但是当报告中调用父查询 - 我得到一个空白报告;因此,如果能朝着正确的方向推动,我们仍然会非常感激。


附录

与上面相同的脚本,但表别名更短(以防有人发现更清晰):

SELECT
  gd.intGagePOID,
  gd.strGageDetailID,
  gm.Description,
  gm.Manufacturer,
  gm.Model_No,
  gm.Gage_SN,
  gm.Unit_of_Meas,
  gm.User_Defined,
  gm.Calibration_Frequency,
  gm.Calibration_Frequency_UOM,
  gd.bolGageLeavePriceBlank,
  gd.intGageCost,
  gm.Last_Calibration_Date,
  gm.Next_Due_Date,
  gd.bolGageEvaluate,
  gd.bolGageExpedite,
  gd.bolGageAccredited,
  gd.bolGageCalibrate,
  gd.bolGageRepair,
  gd.bolGageReturned,
  gd.bolGageBER,
  gd.intTurnaroundDaysOut,
  lu.MaxOfdatDateEntered
FROM (dbo_tblPOGaugeDetail gd
  INNER JOIN dbo_Gage_Master gm ON gd.strGageDetailID = gm.Gage_ID)
  INNER JOIN qryRCEquipmentLastUse lu ON gm.Gage_ID = lu.Gage_ID
ORDER BY gd.strGageDetailID;

BACKGROUND:
I've been trying to streamline the work involved in running a report in my program. Lately, I've had to supply a listing of job numbers an instrument has been used on with the listing of items for cost/benefit analysis. Mostly to see how often an instrument is used since it was last serviced/calibrated and the last time anyone did use it. I was looking to integrate this into the query that helps generate the report - but I keep hitting a brick wall of sorts with the number of uses - since I want that aggregate to be based on the date the instrument was last calibrated (a field based in the same query). I can get it to give me the number of uses in the system total - but it will not accept the limitation that I want it to be only counting the times used since the last time it was calibrated

PROBLEM:
Attempts to put an aggregate function in my report for the number of uses since the item's calibration are met either with undesired results, or the dreaded 'aggregate missing' error (don't remember the exact warning).

-- Edited to add 8/12/2011 @ 16:09 --

An additional problem with the use of the Max aggregate has been found for instruments that have never been used being excluded by this query.

DETAILS:

Here is the query that does work so far:

SELECT
  dbo_tblPOGaugeDetail.intGagePOID,
  dbo_tblPOGaugeDetail.strGageDetailID,
  dbo_Gage_Master.Description,
  dbo_Gage_Master.Manufacturer,
  dbo_Gage_Master.Model_No,
  dbo_Gage_Master.Gage_SN,
  dbo_Gage_Master.Unit_of_Meas,
  dbo_Gage_Master.User_Defined,
  dbo_Gage_Master.Calibration_Frequency,
  dbo_Gage_Master.Calibration_Frequency_UOM,
  dbo_tblPOGaugeDetail.bolGageLeavePriceBlank,
  dbo_tblPOGaugeDetail.intGageCost,
  dbo_Gage_Master.Last_Calibration_Date,
  dbo_Gage_Master.Next_Due_Date,
  dbo_tblPOGaugeDetail.bolGageEvaluate,
  dbo_tblPOGaugeDetail.bolGageExpedite,
  dbo_tblPOGaugeDetail.bolGageAccredited,
  dbo_tblPOGaugeDetail.bolGageCalibrate,
  dbo_tblPOGaugeDetail.bolGageRepair,
  dbo_tblPOGaugeDetail.bolGageReturned,
  dbo_tblPOGaugeDetail.bolGageBER,
  dbo_tblPOGaugeDetail.intTurnaroundDaysOut,
  qryRCEquipmentLastUse.MaxOfdatDateEntered
FROM (dbo_tblPOGaugeDetail
  INNER JOIN dbo_Gage_Master ON dbo_tblPOGaugeDetail.strGageDetailID = dbo_Gage_Master.Gage_ID)
  INNER JOIN qryRCEquipmentLastUse ON dbo_Gage_Master.Gage_ID = qryRCEquipmentLastUse.Gage_ID
ORDER BY dbo_tblPOGaugeDetail.strGageDetailID;

But I can't seem to aggregate a count of Uses (making a Count(strCustomerJobNum)) from the tblGageActivity with the following fields:

strGageID
strCustomerJobNum
datDateEntered
datTimeEntered

I tried to add a field to the formerly listed query to do a Count(strCustomerJobNum) where datDateEntered matched the Last_Calibration_Date from the calling query - but I got the 'missing aggregate' error. If I leave this condition out - it will run - but will list every instrument ever sent out only if it's had a usage count of at least one (not what I want at all, sadly).

I also want to make sure that if I should get a zero uses count - I will get a zero back instead of my expected records minus the null results.

I hope someone out there can tell me where I am going wrong with this - I want to save the time I am currently spending running an activity report in another program whenever I want to generate this report. Thanks in advance, and let me know if you need me to post more information.

-- Edited to add 08/15/2011 @ 14:41 --

I managed to solve the Max() aggregate problem by creating a 'pure' first-step query to get a listing of all instrument with most modern date as qryRCEquipmentUsed.

qryRCEquipmentLastUse:

SELECT dbo.tblGageActivity.strGageID, Max(dbo.tblGageActivity.datDateEntered) AS datLastDateUsed
FROM dbo.tblGageActivity
GROUP BY dbo.tblGageActivity.strGageID;

Then I created a 'pure' listing of all instruments that have no usage at all as a query named qryRCEquipmentNeverUsed.

qryRCEquipmentNeverUsed:

SELECT dbo_Gage_Master.Gage_ID, NULL AS datLastDateUsed
FROM dbo_Gage_Master LEFT JOIN dbo_tblGageActivity ON dbo_Gage_Master.Gage_ID = dbo_tblGageActivity.strGageID
WHERE (((dbo_tblGageActivity.strGageID) Is Null));

NOTE: The NULL was inserted so that the third combining UNION query will not fail due to a mismatch in the number of fields being retrieved from the tables.

At last, I created a UNION query named qryCombinedUseEquipment to combine the two into a list:

qryCombinedUseEquipment:

SELECT *
FROM qryRCEquipmentLastUse
UNION SELECT *
FROM qryRCEquipmentNeverUsed;

Using this last union query to feed the Last Used date to the parent query works in datasheet view, but when the parent query is called in the report - I get a blank report; so a nudge in the right direction would still be wonderfully appreciated.


APPENDIX

Same script as above, but with shorter table aliases (in case someone finds that clearer):

SELECT
  gd.intGagePOID,
  gd.strGageDetailID,
  gm.Description,
  gm.Manufacturer,
  gm.Model_No,
  gm.Gage_SN,
  gm.Unit_of_Meas,
  gm.User_Defined,
  gm.Calibration_Frequency,
  gm.Calibration_Frequency_UOM,
  gd.bolGageLeavePriceBlank,
  gd.intGageCost,
  gm.Last_Calibration_Date,
  gm.Next_Due_Date,
  gd.bolGageEvaluate,
  gd.bolGageExpedite,
  gd.bolGageAccredited,
  gd.bolGageCalibrate,
  gd.bolGageRepair,
  gd.bolGageReturned,
  gd.bolGageBER,
  gd.intTurnaroundDaysOut,
  lu.MaxOfdatDateEntered
FROM (dbo_tblPOGaugeDetail gd
  INNER JOIN dbo_Gage_Master gm ON gd.strGageDetailID = gm.Gage_ID)
  INNER JOIN qryRCEquipmentLastUse lu ON gm.Gage_ID = lu.Gage_ID
ORDER BY gd.strGageDetailID;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千年*琉璃梦 2024-12-06 02:16:35

一点一点...

首先——我怀疑您试图一次回答太多问题(正如 SELECT 中的 23 个字段所证明的那样),这将使聚合几乎不可能。首先缩小查询的范围——这个查询试图回答什么问题? (您随时可以提出更多查询来回答其他问题...:-)

1) 自上次校准以来有多少次使用?
2) 自上次使用以来有多少次使用...使用? (不确定您的意思 - 也许是上次注销,或上次租赁等?)

提示 - 学习使用表别名。大型查询难以阅读;由于重复的表名而变得更糟。

1) 例如:dbo_tbl_POGaugeDetail.intGagePOID 变为 d.intGagePOID

以下是一个可以帮助您入门的示例:

SELECT
   d.strCustomerJobNum,
   Max(d.last_calibration_date) -- not sure what you named that field
   Count(d.strCustomerJobNum)
FROM
   dbo_tblPOGaugeDetail d
GROUP BY
   d.strCustomerJobNum

Piece by piece...

First -- I suspect you're trying to answer too many questions at once (as evidenced by 23 fields in your SELECT), which will make aggregation near-impossible. Start by narrowing down the scope of the query -- What question is this query attempting to answer? (You can always make more queries to answer other questions... :-)

1) How many uses since last calibration?
2) How many uses since last ...use? (not sure what you mean by that -- maybe last sign-out, or last rental, etc.?)

Tip -- learn to use table aliases. Large queries are difficult to read; worse because of repeated table names.

1) Ex.: dbo_tbl_POGaugeDetail.intGagePOID becomes d.intGagePOID

Here's a sample that might get you started:

SELECT
   d.strCustomerJobNum,
   Max(d.last_calibration_date) -- not sure what you named that field
   Count(d.strCustomerJobNum)
FROM
   dbo_tblPOGaugeDetail d
GROUP BY
   d.strCustomerJobNum
蓝天 2024-12-06 02:16:35

这有效吗:

    SELECT dbo_tblPOGaugeDetail.intGagePOID, dbo_tblPOGaugeDetail.strGageDetailID, 

        OuterGageMaster.Description, OuterGageMaster.Manufacturer,   OuterGageMaster.Model_No, 

        OuterGageMaster.Gage_SN, OuterGageMaster.Unit_of_Meas, OuterGageMaster.User_Defined, 

        OuterGageMaster.Calibration_Frequency, OuterGageMaster.Calibration_Frequency_UOM, 

        dbo_tblPOGaugeDetail.bolGageLeavePriceBlank, dbo_tblPOGaugeDetail.intGageCost, 

        OuterGageMaster.Last_Calibration_Date, OuterGageMasterNext_Due_Date, 

        dbo_tblPOGaugeDetail.bolGageEvaluate, dbo_tblPOGaugeDetail.bolGageExpedite, 

        dbo_tblPOGaugeDetail.bolGageAccredited, dbo_tblPOGaugeDetail.bolGageCalibrate, 

        dbo_tblPOGaugeDetail.bolGageRepair, dbo_tblPOGaugeDetail.bolGageReturned, 

        dbo_tblPOGaugeDetail.bolGageBER, dbo_tblPOGaugeDetail.intTurnaroundDaysOut, 

        qryRCEquipmentLastUse.MaxOfdatDateEntered,

        (Select Count(strCustomerJobNum) 

             FROM tblGageActivity WHERE   

              OuterGageMaster.Last_Calibration_Date=tblGageActivity.datDateEntered) As   JobCount

FROM 

    (dbo_tblPOGaugeDetail INNER JOIN dbo_Gage_Master OuterGageMaster ON 

    dbo_tblPOGaugeDetail.strGageDetailID = OuterGageMaster.Gage_ID) INNER JOIN 

    qryRCEquipmentLastUse ON OuterGageMaster.Gage_ID = qryRCEquipmentLastUse.Gage_ID

ORDER BY

 dbo_tblPOGaugeDetail.strGageDetailID;

还是你尝试过的?

Does this work:

    SELECT dbo_tblPOGaugeDetail.intGagePOID, dbo_tblPOGaugeDetail.strGageDetailID, 

        OuterGageMaster.Description, OuterGageMaster.Manufacturer,   OuterGageMaster.Model_No, 

        OuterGageMaster.Gage_SN, OuterGageMaster.Unit_of_Meas, OuterGageMaster.User_Defined, 

        OuterGageMaster.Calibration_Frequency, OuterGageMaster.Calibration_Frequency_UOM, 

        dbo_tblPOGaugeDetail.bolGageLeavePriceBlank, dbo_tblPOGaugeDetail.intGageCost, 

        OuterGageMaster.Last_Calibration_Date, OuterGageMasterNext_Due_Date, 

        dbo_tblPOGaugeDetail.bolGageEvaluate, dbo_tblPOGaugeDetail.bolGageExpedite, 

        dbo_tblPOGaugeDetail.bolGageAccredited, dbo_tblPOGaugeDetail.bolGageCalibrate, 

        dbo_tblPOGaugeDetail.bolGageRepair, dbo_tblPOGaugeDetail.bolGageReturned, 

        dbo_tblPOGaugeDetail.bolGageBER, dbo_tblPOGaugeDetail.intTurnaroundDaysOut, 

        qryRCEquipmentLastUse.MaxOfdatDateEntered,

        (Select Count(strCustomerJobNum) 

             FROM tblGageActivity WHERE   

              OuterGageMaster.Last_Calibration_Date=tblGageActivity.datDateEntered) As   JobCount

FROM 

    (dbo_tblPOGaugeDetail INNER JOIN dbo_Gage_Master OuterGageMaster ON 

    dbo_tblPOGaugeDetail.strGageDetailID = OuterGageMaster.Gage_ID) INNER JOIN 

    qryRCEquipmentLastUse ON OuterGageMaster.Gage_ID = qryRCEquipmentLastUse.Gage_ID

ORDER BY

 dbo_tblPOGaugeDetail.strGageDetailID;

or is that what you tried?

画中仙 2024-12-06 02:16:35

总结问题:

尝试在我的报告中添加一个聚合函数来计算使用次数,因为该项目的校准要么出现不期望的结果,要么出现可怕的“聚合缺失”错误。

解决方案

我决定让查询单独驱动报表 - 相反,选择适当使用 DLookup 和 DCount 从提供所有数据的上次使用日期的查询中检索上次使用的日期。仪器,以及仪器自上次校准以来的使用次数,分别使用上述域聚合。

使用问题描述中描述的查询,我能够检索所有仪器的上次使用日期。我使用 =DLookup 语句作为报表子报表上处理各种项目的文本框的源,如下所示:

=IIf((DLookUp("[qryRCCombinedUseEquipment]![datLastDateUsed]","[qryRCCombinedUseEquipment]","[qryRCCombinedUseEquipment]![strGageID]=[strGageDetailID]")) Is Null Or ([bolGageReturned]=True),"",DLookUp("[qryRCCombinedUseEquipment]![datLastDateUsed]","[qryRCCombinedUseEquipment]","[qryRCCombinedUseEquipment]![strGageID]=[strGageDetailID]"))

这允许从未使用过的项目返回 NULL 结果,该结果将显示为空白文本框。

然而,使用次数不会通过使用 =DCount 的查询来提供(我尝试过,如果有的话,检索结果将需要十多分钟)。然而,使用底层活动表,我使用了以下语句:

=IIf([bolGageReturned],"","Used " & DCount("[dbo_tblGageActivity]![strGageID]","[dbo_tblGageActivity]","[dbo_tblGageActivity]![strGageID] = [strGageDetailID] And [dbo_tblGageActivity]![datDateEntered]  Between [txtLastCalibrationDate] And date()") & " times since last calibration")

它将检索自上次校准仪器以来的使用次数,但不会检索当天之前或之后的使用情况(奇怪的是,有些作业是过时的)。当然,这很慢(对于包含三十或四十台仪器的大型文档来说大约三十秒)。

其他人对此有更好的解决方案吗?还是我必须承受性能损失?如果没有人有更好的想法,我会在五天(8/21/2011)后接受这个答案。

Summary Problem:

Attempts to put an aggregate function in my report for the number of uses since the item's calibration are met either with undesired results, or the dreaded 'aggregate missing' error.

Solution:

I decided to leave the query driving the report alone - instead choosing to employ the use of DLookup and DCount as appropriate to retrieve the last used date from a query that provides the last used date of all the instruments, and the number of uses an instrument has had since it's last calibration, using the aforementioned domain aggregates respectively.

Using the query described in the problem description, I am able to retrieve the last used date for all instruments. I used a =DLookup statement as the source for a text box on the report's subreport dealing with various items as such:

=IIf((DLookUp("[qryRCCombinedUseEquipment]![datLastDateUsed]","[qryRCCombinedUseEquipment]","[qryRCCombinedUseEquipment]![strGageID]=[strGageDetailID]")) Is Null Or ([bolGageReturned]=True),"",DLookUp("[qryRCCombinedUseEquipment]![datLastDateUsed]","[qryRCCombinedUseEquipment]","[qryRCCombinedUseEquipment]![strGageID]=[strGageDetailID]"))

This allows items that have never been used to return a NULL result, which will display as a blank text box.

The number of uses, however, would not feed off a query using =DCount (I tried, it would take over ten minutes to retrieve results, if it ever did). However, using the underlying activity table, I used the following statement:

=IIf([bolGageReturned],"","Used " & DCount("[dbo_tblGageActivity]![strGageID]","[dbo_tblGageActivity]","[dbo_tblGageActivity]![strGageID] = [strGageDetailID] And [dbo_tblGageActivity]![datDateEntered]  Between [txtLastCalibrationDate] And date()") & " times since last calibration")

It would retrieve a number of times used since the instrument was last calibrated, but no uses that are before that or after today (some jobs are post dated, strangely). Of course, this is SLOW (about thirty seconds for a large document with thirty or forty instruments).

Does anyone else have a better solution for this, or will I have to take the performance hit? If no one has any better ideas, I will accept this as the answer after five days (8/21/2011) .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文