Pendekatan
Anda memiliki dua kesalahan dalam pendekatan Anda, yang menimbulkan kerumitan.
-
Kolom apa pun yang dapat diturunkan, seperti RATA-RATA Anda seharusnya tidak disimpan.
Jika disimpan, itu merupakan kolom duplikat ... yang mengarah ke Anomali Pembaruan, seperti yang Anda alami. Inti dari Normalisasi adalah untuk menghilangkan duplikasi data, dan dengan demikian menghilangkan Anomali Pembaruan. Ini juga menghilangkan kode kompleks seperti ini, serta pemicu, dll.
Hitung SUM(), AVG(), dll, dalam set hasil hanya , dengan cepat.
-
Penggunaan kolom ID, yang pada dasarnya berarti Anda memiliki Sistem Pengarsipan Catatan, tidak ada Basis Data Relasional. Tanpa menyebutkan banyak masalah yang ditimbulkannya (saya telah melakukannya di tempat lain), sebutkan saja masalahnya di sini
- Anda memiliki pola pikir ID.
ID adalah penunjuk catatan fisik, tidak memberikan keunikan baris, seperti yang diperlukan untuk Basis Data Relasional.
ID adalah penunjuk catatan fisik, tidak berarti apa-apa, pengguna tidak boleh melihatnya. Tetapi Anda (dan orang lain) telah memberinya makna.
Yang merekatkan Anda ke struktur fisik file, bukan struktur logis data. Yang pada gilirannya memperumit kode Anda.
Oleh karena itu, tanpa memberi Anda
CREATE TABLE
yang dikoreksi perintah, biarkan milik Anda apa adanya, mari kita berpura-pura bahwa ID, dan RATA-RATA, tidak ada dalam file.
Item ketiga, tidak terkait dengan pendekatan, tampaknya dari gambar yang diberikan, 10,58, Anda menginginkan Kilometer per liter, sedangkan aritmatika yang telah Anda perinci (Liter per 100 Km) akan menghasilkan 9,44. Jika Anda menginginkan rata-rata, lebih baik Anda mencari tahu elemennya terlebih dahulu.
Solusi
(Code obsolete due to revision)
Pertanyaan yang Direvisi
Saya mencoba untuk mendapatkan angka yang Anda berikan, sementara pertanyaannya tetap membingungkan (perhatikan komentar untuk efek itu). Karena Anda telah Direvisi pertanyaan Anda, persyaratannya sekarang jelas. Sekarang tampaknya Anda menginginkan (a) Liter per 100 Km [masih bukan "rata-rata"], dan (b) angka keseluruhan untuk setiap rekor [semacam total lari]. Dalam hal ini, gunakan kode ini.
Catatan di atas tetap berlaku dan berlaku.
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
Perhatikan saya memanipulasi data, dan hanya data, tidak ada bidang fisik, kita tidak perlu peduli dengan aspek fisik file. Liter per 100 Km (apa yang Anda sebut RATA-RATA) tidak disimpan, dan di sana Anomali Pembaruan dihindari. Angka keseluruhan untuk setiap catatan dihitung "on the fly", hanya pada waktu tampilan.
Ini juga menghilangkan /first entry
masalah.
Tentu saja, CARID
juga tidak berarti bagi pengguna.
Silakan berkomentar atau mengajukan pertanyaan, dll.
Penyimpanan Keras
Ada banyak masalah dengan menyimpan nilai yang dapat diturunkan. Ini adalah Hard-coding di tingkat penyimpanan data. Tentu, Anda dapat menggunakan pemicu untuk meringankan rasa sakit, tetapi itu tetap tidak akan berhasil, karena (a) prinsipnya rusak dan (b) itu melanggar prinsip teknik yang ada. Misalnya. apa yang terjadi ketika LI untuk satu baris salah dimasukkan (mis. 700.17), dan kemudian dikoreksi (mis. 70.17)? Semua baris berikutnya untuk mobil itu sekarang salah, dan harus dihitung ulang, dan diperbarui. Jadi sekarang Anda memerlukan pemicu Pembaruan serta pemicu Sisipkan. Senyawa kanker itu sendiri.
Konsep Anomali Pembaruan, larangan menyimpan nilai yang dapat diturunkan, telah ada sejak tahun 1970, untuk alasan yang baik. Kami menghindarinya, untuk alasan yang bagus.