Etkili tarihleri ​​olan fiyatları nasıl saklayabilirim?


21

Ürün listem var. Her biri N sağlayıcılar tarafından sunulmaktadır.

Her sağlayıcı bize belirli bir tarih için bir fiyat veriyor. Bu fiyat sağlayıcı, yeni bir fiyat belirlemeye karar verene kadar geçerlidir. Bu durumda, sağlayıcı yeni fiyatı yeni bir tarihle verir.

MySQL tablo başlığı şu anda şuna benziyor:

provider_id, product_id, price, date_price_effective

Her geçen gün, o gün için geçerli olan ürünlerin / fiyatların bir listesini derliyoruz. Her ürün için, listede söz konusu ürüne sahip sağlayıcıların sıralanmış bir listesi bulunur. Bu şekilde, en iyi fiyatı sunmak için olanlardan belirli ürünleri sipariş edebiliriz.

Etkili fiyat almak için, tüm satırları döndüren bir SQL deyim var date_price_effective >= NOW(). Bu sonuç kümesi, şuna benzeyen bir dosyayı elde etmek için gereken sıralama ve filtrelemeyi yapan bir yakut komut dosyası ile işlenir:

product_id_1,provider_1,provider_3,provider8,provider_10...
product_id_2,provider_3,provider_2,provider1,provider_10...

Bu bizim amaçlarımız için gayet iyi fakat hala bir SQL tablosunun bu tür bilgileri depolamak için en iyi yol olmadığını belirten bir kaşıntıya sahibim. Bu tür problemlerin daha önce başka yaratıcı yollarla çözüldüğünü hissediyorum.

Bu bilgiyi SQL dışında saklamanın daha iyi bir yolu var mı? veya, eğer SQL kullanıyorsanız, kullandığımdan daha iyi bir yaklaşım var mı?


lal00: ​​Yorumlarımdan birinde belirttiğim gibi, düzenli olarak etkili randevu alıyorum. Lütfen basit bir etkili tarih işleme yöntemi için cevabımı bakın. Yeni bir fiyat satırı oluşturulurken bir fiyatın geçerli olduğu sürenin bilinmesini, yeni bir satır oluşturulduğunda önceki en güncel satırın değiştirilmesini geri almak gerekmez.
bit twiddler

Yanıtlar:


17

Zamana göre değişen öğeler için ("D tarihinin X fiyatı neydi" ya da "E'nin tarihindeki Q feedlot'unda hangi ineğin Q olduğu" gibi şeyleri cevaplayabilmek gibi) SQL'de Veritabanı Uygulamaları. " Bu kitabın baskısı tükenmekle birlikte, yazar, kitabın PDF'sini ve web sitesinde ilgili CD'yi nezaketle hazırlamıştır.

http://www.cs.arizona.edu/~rts/publications.html ("kitaplar" altındaki ilk öğeyi arayın).

Çevrimiçi kısa bir giriş için, bakınız:


1
Sorduğumda aklımdaki bu değildi, daha iyi! :)
edmz

3

Etkili tarihi kesinlikle veritabanında saklardım. Sonuçta, insanların fiyatın zaman içinde nasıl değiştiğini görmek için sorgulamalar yapmak ya da geçmiş ürün fiyat tablosuna göre siparişlerdeki tuhaflıkları kontrol etmek isteyebilecekleri muhtemeldir. Çalıştığınız sorguların türüne ve fiyat değişiklik sıklığına bağlı olarak, geçerli fiyat ve geçmiş fiyatlar için ayrı tablolara sahip olmak mantıklı olabilir.

Fiyatları saklayan çoğu sistemde, geçerli fiyatın geçerli olduğunu belirlemeyi kolaylaştırmak için geçerli olan tarihe ek olarak bir son kullanma tarihi sütunu istersiniz; belirli bir zamanda hangi fiyatın geçerli olduğunu anlamak. NOW() >= date_price_effectiveDurumunuzun ne yaptığı konusunda net değilim - muhtemelen, şu anki fiyatı bana tuhaf görünen önceki tüm tarihsel fiyatlarla birlikte geri veriyor. "Etkili fiyat" ın, şu gibi bir şeyle tanımlanacak mevcut fiyat olacağını düşünüyorum.NOW() BETWEEN date_price_effective AND date_price_expired

Dosyanızın neye benzemesi gerektiğinden de emin değilim. Bana neyin neyi provider_1temsil ettiği açıkça belli değil - sağlayıcı_dosyası = 1 fiyat? - ya da sağlayıcı verilerini nasıl sipariş ettiğin - neden provider_1birinci product_id_1ve üçüncü için görünüyor product_id_2?


Justin, son kullanma tarihi mantıklı. Haklıydın, etrafta SQL vardı. Çıktı dosyası sorumla pek ilgili değil, sadece fiyatları fiyatlara göre sıralamak istediğimi örneklendirmenin bir yolunu ekledim.
edmz

Birinin, her satırda bir son kullanma tarihi içermesine gerek yoktur, çünkü sadece ek bir ek yük ekler, çünkü genellikle bir satır oluşturulduğunda geçerli olan bir fiyatın geçerli olduğu bir süre belirtilmez. Bir tabloda, her biri belirli bir tarihte geçerli olan her bir üretici_id / product_id çifti için N satırımız varsa, belirtilen tarihin altında veya bu değere eşit olan en büyük date_price_effective değeri olan satır, geçerli olan fiyattır. şu tarihte. Yazılarıma bakarsanız, bu tür bir sorguyu gerçekleştiren SQL kodunu göreceksiniz. Düzenli olarak etkili tarihlerle uğraşmak zorundayım.
bit-twiddler

@ bit-twiddler - Kesinlikle, bir son kullanma tarihine sahip olmak gerekli değildir. Ancak, son kullanma tarihine sahip olmak, genellikle tabloyu sorgulamayı çok daha kolay ve daha verimli hale getirir. Geçerli tarih sorguları genellikle fiyat değişikliklerinden çok daha yaygın olduğundan, bu genellikle yapmaktan memnuniyet duyduğum bir takas.
Justin Cave

3

Sorun ifadenizi doğru anlarsam, genel verileri işlemek için bir yola ihtiyacınız vardır (örneğin, tablo her biri tarih duyarlı olan her sağlayıcı_d / product_id çifti için birden çok satır içerir). Bu durumda, date_price_effective değeri olan bir ürünün en düşük fiyatını bugünden daha düşük veya ona eşit arıyorsunuzdur. Bu tür bir durum, bir SQL alt seçimi kullanılarak kolayca gerçekleştirilebilir.

 SELECT 
   provider_id, product_id, price, date_price_effective 
 FROM 
   price_table a 
 WHERE 
   date_price_effective = 
     (
       SELECT 
         MAX(date_price_effective) 
       FROM 
         price_table b 
       WHERE 
         b.provider_id = a.provider_id AND 
         b.product_id = a.product_id AND
         b.date_price_effective <= NOW() 
     );

Bir fiyat, sorgunun yürütüldüğü tarihe eşit veya daha az olan en büyük date_price_effective değerine sahip olduğu sürece geçerlidir. Günümüzden büyük bir date_price_effective değeri, gelecekteki geçerli bir tarihtir. Yukarıda listelenen kod, sorgunun çalıştırıldığı tarihten en yakın, ancak daha sonra değil date_price_effective değerine sahip her sağlayıcı_d / product_id çifti için satır verilerini döndürür. Çözüm, fiyatları otomatik olarak geçerli tarih aralıklarına yerleştirir. Bu tablonun birincil anahtarı, üçlü {sağlayıcı_adı, ürün_adı, date_price_effective};

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.