Правилното съхраняване на данни за продажбите и последващото им комбиниране може да доведе до създаване на прогнозен модел с висока степен на точност. В тази и следващите няколко статии ще анализираме дизайн на база данни за записване на продажби.
Всеки живее, продавайки нещо.
Робърт Луис Стивънсън
В днешния свят, продажба на продукти е повсеместен. А продавачите, които имат достъп до стабилни инструменти, които използват исторически данни, за да анализират тенденциите и да позволят на предприятието да коригира съответно бизнес стратегиите си, имат предимство пред своите конкуренти. Има много параметри, които могат да повлияят на резултатите на компанията:текущата световна икономическа ситуация, местоположение на клиентите, възраст, материално и семейно положение и история на предишни контакти или продажби на клиенти.
Ще започнем с много прост пример:модел на база данни за продажби в кафене . В следващите статии ще разширим модела до продажба на продукти в други клонове.
Модел на продажби
В тази статия ще анализираме само част от модела, който съдържа данни за продажбите с липсващи други части.
Все още имаме връзки с липсващи таблици и ще гледаме на модела като на черна кутия, като приемем, че следното е правилно за таблица sale
:
user_has_role_id
вижте идентификатора вuser_has_role
(както е представено в предишната ми статия в раздел „Добавен компонент за време“) и съхранява информация за потребителя, създал запис за продажба
Този модел ни позволява да създаваме записи за продажби с множество артикули. Всеки артикул е свързан с продукт от нашия каталог. Моментът, в който генерираме продажба, може да бъде различен от момента, в който продажбата е платена. Например, за чаша кафе тези моменти ще се различават за няколко минути или часове. Ако нашият магазин продава телекомуникационни устройства, разликата може да бъде няколко дни, може би дори месеци.
Таблици
Нека да разгледаме дефиницията на таблицата и да обясним целта и използването на атрибутите.
Най-важната таблица в модела е product
. Използва се за съхраняване на подробности за продуктите, които ще предложим на нашите клиенти. Продуктите обикновено се доставят на клиент и се заплащат еднократно, обикновено в момента на доставка. Освен това продуктите обикновено са физически обекти като автомобили, телефони, опаковки със захар или чаши кафе.
Ще говорим за продажба на нефизически неща (услуги) в следващите статии.
Атрибути в product
таблицата са:
name
– името на продукта в систематаprice_per_unit
– цена на продукта за единица (например 1 чаша кафе струва 1,8 евро, 1 кола струва 17 500 евро, 1 кг ориз струва 2 евро)basic_unit
– базова единица, когато продаваме продукт (напр. парче, кг, литър)tax_percentage
– процент от цената_на_единица, която трябва да бъде начислена като данък. Трябва да приемем, че данъчният процент няма да е еднакъв за всички продуктиlimited
– това поле е зададено на True, ако имаме ограничено количество на склад и False в противен случай (например, можем да поръчаме всяко количество, което ни е необходимо за нашия магазин от дистрибутор)in_stock
– if limited=True този атрибут показва колко имаме на разположение за продажбаactive_for_sale
– ако този атрибут е False, тогава в момента не предлагаме този продукт за продажба, в противен случай можем да го предложим на клиенти
Можем да получим списък с продукти, които можем да предложим на клиентите със следното запитване:
SELECT product.id, product.price_per_unit, product.basic_unit, product.limited, product.in_stock FROM product WHERE product.active_for_sale = True AND (product.limited = False OR (product.limited = True and product.in_stock > 0))
Таблицата sale_status
е просто прост речник, който съдържа всички състояния, които една продажба може да има в системата (напр. „разписка издадена“, „разписка платена“).
Таблицата
sale
е втората най-важна маса в този модел. Засега тази таблица няма връзка с клиенти, на които сме продавали продукти, тъй като в нашия пример с кафене не е необходимо да знаем такава информация. В част 2 моделът ще бъде разширен, за да обхване такива случаи. Атрибутите в таблицата и техните значения са:
time_created
– време, когато в системата е генериран запис за продажба (например автоматично време, в което записът е създаден, когато генерираме продажба за кафе в нашето кафене или ръчно добавен час, ако искаме така)time_paid
– като цяло можем да очакваме, че някои продажби ще бъдат изплатени в рамките на няколко дни или дори месец след създаването (например, ако доставим софтуер и създадем разписка, можем да изчакаме до 90 дни, за да получим плащане в някои страни, ако всичко мине закона)sale_amount
– първоначална сума, предназначена за таксуване на клиентаsale_amount_paid
– сума, която клиентът действително е заплатил. Може да е нула, защото в момента, в който създаваме разписка, не винаги разполагаме с тази информацияtax_amount
– сбор от всички данъчни суми за артикули в тази разпискаsale_status_id
– препратка къмsale_status
таблицаuser_has_role_id
– препратка към потребителя и неговата роля в момента, в който е въвел разписката в системата
Можем да получим издадената и платена сума (според time_created) в рамките на период от време със заявка като тази:
SELECT SUM(sale.sale_amount) AS amount_issued, SUM(sale.sale_amount_paid) AS amount_paid FROM sale WHERE sale.time_created >= @start_time AND sale.time_created <= @end_time;
За да получим точната сума, платена в рамките на определен период от време, трябва да използваме заявка като тази:
SELECT SUM(sale.sale_amount_paid) AS amount_paid FROM sale WHERE sale.time_paid >= @start_time AND sale.time_paid <= @end_time;
Заявката по-долу ще изчисли издадената и платената сума в рамките на период от време, като датата на издаване и датата на плащане са проверени отделно:
SELECT SUM(CASE WHEN sale.time_created >= @start_time AND sale.time_created <= @end_time THEN sale.sale_amount END) AS amount_issued, SUM(CASE WHEN sale.time_paid >= @start_time AND sale.time_paid <= @end_time THEN sale.sale_amount_paid END) AS amount_paid FROM sale
Във всички примери @start_time
и @end_time
са променливи, съдържащи началния и крайния час на периода, за който искаме да проверим издадената и платена SUM.
Таблицата sale_item
свързва продукти и продажби. Разбира се, трябва да приемем, че ще имаме множество артикула на една разписка, така че се нуждаем от тази таблица, за да имаме връзка много към много.
Атрибутите и техните значения са:
quantity_sold
– количество продукт, който е бил продаден и се таксува при тази продажба/разписка (напр. 3 кафета)price_per_unit
– същата стойност катоproduct.price_per_unit
в момента, в който е създадена продажбата. Трябва да го запазим, защотоprice_per_unit
вproduct
таблицата може да се променя с течение на времетоprice
– продукт наquantity_sold
иprice_per_unit
; малък излишък, който ни помага да избегнем това изчисление в заявките. Като цяло, сумата от всички цени на артикули, принадлежащи към една и съща продажба, трябва да е равна наsale.sale_amount
tax_amount
– сума на данъка за този артикул при получаванеsale_id
– идентификатор на продажба, на който принадлежи този артикулproduct_id
– идентификатор на продукта, свързан с този артикул
Вече можем лесно да направим прост отчет, колко продукти/услуги сме продали за период и на каква цена.
SELECT product.name, SUM(sale_item.quantity_sold) AS quantity, SUM(sale_item.price) AS price FROM sale, sale_item, product WHERE sale.id = sale_item.sale_id AND sale_item.product_id = product.id AND sale.time_created >= @start_time AND sale.time_created <= @end_time GROUP BY product.id