2

個々のカートリッジの印刷使用量を抽出するSQLクエリを作成しています。以下のようにクエリの本体を取得しましたが、別のテーブルに保存されているメーターの読み取り値を処理するための特定のデータを選択するのに問題があります。

以下のクエリは、プリンタに挿入されたカートリッジと、それらがアクティブ化された日付と非アクティブ化された日付を示しています。次に、MeterReadingsテーブルを使用して、DeviceIDに基づいてActivatedDateとDeactivateDateを使用して、その期間の使用状況を確認したいと思います。私がこれまでに持っているものは以下です

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

これにより、現在、「HAVING句または選択リストに含まれるサブクエリに含まれていない限り、集計がWHERE句に表示されない可能性があり、集計される列が外部参照である」というエラーが発生します。

計算フィールドActivatedDateとDeactivateDateは、私が必要とする日付範囲です。caseステートメントを使用して、白黒の場合はMAX(MeterReadings.TotalMono)-MIN(MeterReadings.TotalMono)を選択し、色の場合はMAX(MeterReadings.TotalColour)-MIN(MeterReadings.TotalColour)を選択します。読み取り値は上向きにしかできないので、これは効果的に使用法を与えてくれます。これにより、特定のDeviceIDについて、MINでの開始点の使用法とMAXでの終了点の使用法がわかります。

上に示したように、DeviceIDのMeterReadingsテーブルに参加しています。

デバイスxのMeterReadingsをyとzの間(xはDeviceID、yはActivatedDate、zはDeactivateDate)で取得する方法がわからないため、計算された列をcaseステートメントに追加できます。助けていただければ幸いです。

--編集簡潔にするために、ここにすべてのスキーマを追加するわけではありませんが、十分なはずです。

デバイス-すべての既知のデバイスのリスト

デバイスID

DeviceDescription

デバイスを説明する多くの追加フィールド

DeviceConsumables-どのデバイスがどの消耗品を使用するか

ConsumableID

DeviceID-デバイスへの外部キー

ConsumableVariantID-ConsumableVariantへの外部キー

ConsumableVariant-存在するすべての消耗品バリアントのリスト

ConsumableVariantID

タイプ-3ここで私が興味を持っているトナーを示します

ConsumableReadings

ReadingID-PK

ConsumableID-DeviceConsumablesへの外部キー

ReadingDate-前回読み取りが行われた時刻

ChangedDate-最後に新しいカートリッジが挿入された時刻

MeterReadings

ReadingID-消費可能な読み取り値のPKとは関係のないPK

デバイスID

ScanDateTime-使用量スキャンが行われた時間

TotalMono-スキャン時の合計モノ

TotalColourスキャン時の合計色

4

3 に答える 3

1

クエリをネストされたクエリに分割する必要があります...以下のクエリはテストされていないため、構文に問題がある可能性がありますが、探しているものを見つける方法を提供します...

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
于 2012-06-18T15:09:13.317 に答える
0

あなたの問題はあなたのjoinステートメントにあります。

次の行を変更します。

LEFT JOIN ConsumableTypes ON ConsumableVariants.Type = ConsumableVariants.Type

次のようなものに:

LEFT JOIN ConsumableTypes ON ConsumableVariants.Type = ConsumableTypes.Type

(または参加しているテーブル)。

于 2012-06-18T14:44:08.940 に答える
0

まず、出力に ColourID を追加して、Mono 値と Color 値のどちらを読んでいるかがわかるようにします。第 2 に、group by 句から ConsumableID を削除すると、機能するはずです。ConsumableID 行には 1 つの日付があり、それを group by に含めると、最大値と最小値を取得できないため、違いが生じます。

于 2012-06-18T14:09:46.453 に答える