我正在编写一个SQL查询来提取单个磁带的打印使用情况。我的查询主体如下所示,但我无法选择一些特定数据来处理存储在单独表格中的仪表读数。
以下查询列出了已放入打印机的墨盒及其激活日期和停用日期。然后,我想使用MeterReadings表,根据DeviceID使用ActivatedDate和DeactivatedDate查看该期间的用法。到目前为止我所拥有的是
SELECT Devices.DeviceID,
Devices.DeviceDescription,
DeviceConsumables.ConsumableVariantID,
ConsumableVariants.Type,
ConsumableDescriptions.Description,
MAX(ConsumableReadings.ReadingDate) as DeactivatedDate,
MIN(ConsumableReadings.ReadingDate) AS ActivatedDate,
ConsumableReadings.ChangedDate,
CASE ConsumableVariants.ColourID
WHEN 1 THEN MAX(MeterReadings.TotalMono) - MIN(MeterReadings.TotalMono)
ELSE MAX(MeterReadings.TotalColour) - MIN(MeterReadings.TotalColour)
END AS PrintingDiff,
ConsumableVariants.ExpectedPageCoverage,
ConsumableVariants.ExpectedPageYield
FROM Devices
LEFT JOIN DeviceConsumables ON Devices.DeviceID = DeviceConsumables.DeviceID
LEFT JOIN ConsumableVariants ON DeviceConsumables.ConsumableVariantID = ConsumableVariants.ConsumableVariantID
LEFT JOIN ConsumableReadings ON DeviceConsumables.ConsumableID = ConsumableReadings.ConsumableID
LEFT JOIN ConsumableDescriptions ON ConsumableVariants.DescriptionID = ConsumableDescriptions.ConsumableDescriptionID
LEFT JOIN MeterReadings ON DeviceConsumables.DeviceID = MeterReadings.DeviceID
WHERE ConsumableVariants.Type = '3' -- To only get toner cartridges
AND Devices.DeviceID = '24'
AND MeterReadings.ScanDateTime > MIN(ConsumableReadings.ReadingDate)
AND MeterReadings.ScanDateTime < MAX(ConsumableReadings.ReadingDate)
GROUP BY devices.DeviceID, Devices.DeviceDescription,
DeviceConsumables.ConsumableVariantID, ConsumableVariants.Type, ConsumableDescriptions.Description,
ConsumableReadings.ChangedDate, ConsumableVariants.ColourID, ConsumableVariants.ExpectedPageCoverage,
ConsumableVariants.ExpectedPageYield
ORDER BY Devices.DeviceID
这当前正在生成错误“聚合可能不会出现在WHERE子句中,除非它位于HAVING子句或选择列表中包含的子查询中,并且正在聚合的列是外部引用。”
计算字段ActivatedDate和DeactivatedDate是我需要的日期范围。我想使用case语句选择MAX(MeterReadings.TotalMono) - MIN(MeterReadings.TotalMono)用于黑色或白色或MAX(MeterReadings.TotalColour) - MIN(MeterReadings.TotalColour)用于颜色。这将有效地给我使用,因为读数只能向上。这有望为我提供MIN的起点使用和特定DeviceID的MAX终点用法。
如上所示,我正在加入DeviceID上的MeterReadings表。
我无法弄清楚如何在y和z之间获取设备x的MeterReadings(其中x是DeviceID,y是ActivatedDate,z是DeactivatedDate),因此我可以将一个计算列添加到case语句中。任何帮助表示赞赏。
- 编辑 为简洁起见,我不会在这里添加所有架构,但应该足够了。
设备 - 所有已知设备的列表
的DeviceID
DeviceDescription
许多描述设备的额外字段
DeviceConsumables - 哪些设备使用什么耗材
ConsumableID
DeviceID - 忘记设备密钥
ConsumableVariantID - Forign key to ConsumableVariant
ConsumableVariant - 所有消耗品变体列表
ConsumableVariantID
Type - 3此处表示碳粉,我感兴趣
ConsumableReadings
ReadingID - PK
ConsumableID - 忘记DeviceConsumables的密钥
ReadingDate - 上次阅读时
ChangedDate - 上次插入新墨盒
MeterReadings
ReadingID - PK与耗材读取的PK无关
的DeviceID
ScanDateTime - 已进行时间使用扫描
TotalMono - 扫描时的单声道总数
TotalColour扫描时的总色彩
答案 0 :(得分:0)
首先,我会在您的输出中添加ColourID,以便您知道是否正在读取Mono或Color值。其次,我相信如果您从group by子句中删除ConsumableID,它应该可以工作。 ConsumableID行有一个日期,如果你在你的组中包含它,你将永远无法获得最大值和最小值,因此差异。
答案 1 :(得分:0)
您的问题出在您的加入声明中。
更改以下行:
LEFT JOIN ConsumableTypes ON ConsumableVariants.Type = ConsumableVariants.Type
类似于:
LEFT JOIN ConsumableTypes ON ConsumableVariants.Type = ConsumableTypes.Type
(或您加入的任何表格)。
答案 2 :(得分:0)
嗯,你必须打破你对嵌套查询的查询...下面的查询没有经过测试,所以它可能有一些语法问题,但它提供了一种方法来找出你在寻找...
SELECT Devices.DeviceID,
Devices.DeviceDescription,
DeviceConsumables.ConsumableVariantID,
ConsumableVariants.Type,
ConsumableDescriptions.Description,
A.DeactivatedDate,
A.ActivatedDate,
A.ChangedDate,
CASE ConsumableVariants.ColourID
WHEN 1 THEN MAX(MeterReadings.TotalMono) - MIN(MeterReadings.TotalMono)
ELSE MAX(MeterReadings.TotalColour) - MIN(MeterReadings.TotalColour)
END AS PrintingDiff,
ConsumableVariants.ExpectedPageCoverage,
ConsumableVariants.ExpectedPageYield
FROM Devices
LEFT JOIN DeviceConsumables ON Devices.DeviceID = DeviceConsumables.DeviceID
LEFT JOIN ConsumableVariants ON DeviceConsumables.ConsumableVariantID = ConsumableVariants.ConsumableVariantID
LEFT JOIN ConsumableReadings ON DeviceConsumables.ConsumableID = ConsumableReadings.ConsumableID
LEFT JOIN ConsumableDescriptions ON ConsumableVariants.DescriptionID = ConsumableDescriptions.ConsumableDescriptionID
LEFT JOIN
(
SELECT D.DeviceID,
MAX(CR.ReadingDate) as DeactivatedDate,
MIN(CR.ReadingDate) AS ActivatedDate,
CR.ChangedDate
FROM Devices D
LEFT JOIN DeviceConsumables DC ON D.DeviceID = DC.DeviceID
LEFT JOIN ConsumableReadings CR ON DC.ConsumableID = CR.ConsumableID
WHERE D.DeviceID = '24'
GROUP BY D.DeviceID,
CR.ChangedDate
) AS A ON DeviceConsumables.DeviceID = A.DeviceID
LEFT JOIN MeterReadings ON A.DeviceID = MeterReadings.DeviceID
WHERE ConsumableVariants.Type = '3' -- To only get toner cartridges
AND Devices.DeviceID = '24'
AND MeterReadings.ScanDateTime > A.ActivatedDate
AND MeterReadings.ScanDateTime < A.DeactivatedDate
GROUP BY devices.DeviceID, Devices.DeviceDescription,
DeviceConsumables.ConsumableVariantID, ConsumableVariants.Type, ConsumableDescriptions.Description,
ConsumableReadings.ChangedDate, ConsumableVariants.ColourID, ConsumableVariants.ExpectedPageCoverage,
ConsumableVariants.ExpectedPageYield
ORDER BY Devices.DeviceID