アプローチ
アプローチに2つのエラーがあり、複雑さが生じます。
-
AVERAGEなど、派生可能な列はすべきではありません 保存されます。
保存されている場合、それは重複する列を構成します...これはあなたが経験しているように更新異常につながります。正規化のポイントは、データの重複を排除し、更新の異常を排除することです。また、このような複雑なコードやトリガーなども排除されます。
結果セットのSUM()、AVG()などをのみ計算します。 、オンザフライ。
-
ID列の使用。これは、基本的に、リレーショナルデータベースではなく、レコードファイリングシステムがあることを意味します。それが引き起こす多くの問題を列挙することなく(私は他の場所でそれを行いました)、ここで問題に名前を付けるだけです
- あなたにはIDの考え方があります。
IDは物理レコードポインタであり、リレーショナルデータベースで必要とされる行の一意性を提供しません。
IDは物理レコードポインタであり、何の意味もありません。ユーザーには表示されません。しかし、あなた(そして他の人)はそれに意味を与えました。
これは、データの論理構造ではなく、ファイルの物理構造に接着します。これにより、コードが複雑になります。
したがって、修正された
CREATE TABLE
を提供することなく コマンドをそのままにして、IDとAVERAGEがファイルに存在しないように見せかけましょう。
アプローチに関係のない3番目の項目は、与えられた図10.58から、1リットルあたりのキロメートルが必要なようですが、詳細な計算(100 Kmあたりのリットル)は9.44を生成します。ある種の平均が必要な場合は、最初に要素を把握することをお勧めします。
ソリューション
(Code obsolete due to revision)
改訂された質問
質問が混乱したままで、私はあなたが与えた数字を取得しようとしていました(その趣旨のコメントに注意してください)。 改訂があるので あなたの質問、要件は今明確です。これで、(a)100 Kmあたりのリットル[まだ「平均」ではない]、および(b)各レコードの全体的な数値[一種の累計]が必要なようです。その場合は、このコードを使用してください。
上記の注記は引き続き有効であり、適用されます。
SELECT CARID,
DATETIME,
KM,
LI,
LPCK = ( LI_TOT / ( ( KM_LAST-KM_FIRST / 100 ) ) -- not stored
FROM (
-- create a Derived Table with KM_FIRST
SELECT CARID,
DATETIME,
-- not stored
KM_FIRST = (
SELECT MIN( KM ) -- get the first KM for car
FROM CONSUM
WHERE CARID = C.CARID
),
KM_LAST = (
SELECT MAX( KM ) -- get the last KM for car
FROM CONSUM
WHERE CARID = C.CARID
),
KM, -- KM for this row
LI, -- LI for this row
LI_TOT = (
SELECT SUM( LI ) -- get the total LI for car
FROM CONSUM
WHERE CARID = C.CARID
AND KM != ( -- exclude first LI for car
SELECT MIN( KM ) -- get the first KM for car
FROM CONSUM
WHERE CARID = C.CARID
)
)
FROM CONSUM C
) AS CONSUM_EXT
ORDER BY CARID,
DATETIME
私がデータを操作していることに注意してください。物理フィールドではなく、データのみを操作しているので、ファイルの物理的な側面を気にする必要はありません。 100 Kmあたりのリットル(平均と呼んでいるもの)は保存されず、更新異常が回避されます。各レコードの全体的な数値は、表示時にのみ「オンザフライ」で計算されます。
これにより、/first entry
も削除されます 問題。
もちろん、CARID
同様に、ユーザーにとっても無意味です。
コメントや質問などもお気軽にどうぞ。
ハードストレージ
導出可能な値の保存には多くの問題があります。これは、データストレージレベルでのハードコーディングです。確かに、トリガーを使用して痛みを和らげることはできますが、(a)原則が破られており、(b)既存のエンジニアリング原則に違反しているため、それでも機能しません。例えば。単一行のLIが誤って入力され(例:700.17)、その後修正された場合(例:70.17)はどうなりますか?その車の後続のすべての行は正しくないため、再計算して更新する必要があります。したがって、ここで、更新トリガーと挿入トリガーが必要です。がん化合物自体。
更新異常の概念、つまり導出可能な値の保存の禁止は、正当な理由で1970年以来私たちにありました。正当な理由で、それらを避けます。