Stocker correctement les données de vente et les combiner ultérieurement peut conduire à la création d'un modèle prédictif avec un taux de précision élevé. Dans cet article et les suivants, nous analyserons une conception de base de données pour enregistrer les ventes.
Tout le monde vit en vendant quelque chose.
Robert Louis Stevenson
Dans le monde d'aujourd'hui, vendre des produits est omniprésent. Et les vendeurs qui ont accès à des outils robustes qui exploitent les données historiques pour analyser les tendances et permettre à une entreprise d'ajuster ses stratégies commerciales en conséquence ont un avantage sur leurs concurrents. De nombreux paramètres peuvent affecter les résultats de l'entreprise :la situation économique mondiale actuelle, l'emplacement des clients, leur âge, leur situation matérielle et matrimoniale, ainsi que l'historique des contacts ou des ventes antérieurs aux clients.
Nous allons commencer par un exemple très simple :un modèle de base de données pour les ventes dans un café . Dans les articles suivants, nous étendrons le modèle à la vente de produits dans d'autres branches.
Modèle de vente
Dans cet article, nous n'analyserons qu'une partie du modèle qui contient des données de vente avec d'autres parties manquantes.
Nous avons toujours des connexions aux tables manquantes et nous considérerons le modèle comme une boîte noire en supposant que ce qui suit est correct pour la table sale
:
user_has_role_id
faire référence à l'identifiant dansuser_has_role
(comme présenté dans mon article précédent dans la section "Composant de temps ajouté") et stocke des informations sur l'utilisateur qui a créé l'enregistrement de vente
Ce modèle nous permet de créer des enregistrements de ventes avec plusieurs articles. Chaque article est lié à un produit de notre catalogue. Le moment où nous générons une vente peut être différent du moment où la vente est payée. Par exemple, pour une tasse de café, ces moments différeront en quelques minutes ou quelques heures. Si notre boutique vendait des appareils de télécommunication, la différence peut être de quelques jours, voire de plusieurs mois.
Tableaux
Examinons la définition de table et expliquons le but et l'utilisation des attributs.
La table la plus importante du modèle est product
. Il est utilisé pour stocker des détails sur les produits que nous proposerons à nos clients. Les produits sont généralement livrés à un client et payés une seule fois, généralement au moment de la livraison. En outre, les produits sont généralement des objets physiques tels que des voitures, des téléphones, des paquets de sucre ou des tasses de café.
Nous parlerons de la vente de choses non physiques (services) dans les prochains articles.
Attributs dans le product
le tableau sont :
name
– le nom du produit dans le systèmeprice_per_unit
– coût du produit par unité (par exemple, 1 tasse de café coûte 1,8 euro, 1 voiture coûte 17 500 euros, 1 kg de riz coûte 2 euros)basic_unit
– unité de base lorsque nous vendons un produit (par exemple, pièce, kg, litre)tax_percentage
– pourcentage du price_per_unit à facturer en tant que taxe. Nous devons supposer que le pourcentage de taxe ne serait pas le même pour tous les produitslimited
– ce champ est défini sur True si nous avons une quantité limitée en stock et False sinon (par exemple, nous pouvons commander toute quantité dont nous avons besoin pour notre magasin auprès d'un distributeur)in_stock
– if limited=True cet attribut montre combien nous en avons à vendreactive_for_sale
– si cet attribut est False, nous ne proposons actuellement pas ce produit à la vente, sinon nous pouvons le proposer aux clients
Nous pouvons obtenir une liste des produits que nous pouvons proposer aux clients avec la requête suivante :
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))
Le tableau sale_status
est juste un simple dictionnaire qui contient tous les statuts qu'une vente peut avoir dans le système (par exemple, "reçu émis", "reçu payé").
Le tableau
sale
est la deuxième table la plus importante de ce modèle. Jusqu'à présent, ce tableau n'a aucun lien avec les clients à qui nous avons vendu des produits car, dans notre exemple de café, nous n'avons pas besoin de connaître ces informations. Dans la partie 2, le modèle sera étendu pour couvrir de tels cas. Les attributs du tableau et leurs significations sont :
time_created
– heure à laquelle un enregistrement de vente a été généré dans le système (par exemple, heure automatique à laquelle l'enregistrement a été créé lorsque nous avons généré une vente de café dans notre café ou une heure ajoutée manuellement si nous le souhaitons)time_paid
– généralement, nous pouvons nous attendre à ce que certaines ventes soient payées quelques jours, voire un mois après la création (par exemple, si nous livrons un logiciel et créons un reçu, nous pouvons attendre jusqu'à 90 jours pour être payés dans certains pays, si tout se passe la loi)sale_amount
– montant initial destiné à être facturé au clientsale_amount_paid
– montant que le client a effectivement payé. Il peut être nul car au moment où nous créons un reçu nous n'avons pas toujours cette informationtax_amount
- somme de tous les montants de taxes pour les articles sur ce reçusale_status_id
– référence àsale_status
tableauuser_has_role_id
– référence à l'utilisateur et son rôle au moment où il a saisi le reçu dans le système
Nous pouvons obtenir le montant émis et payé (selon time_created) dans un délai donné avec une requête comme celle-ci :
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;
Pour obtenir le montant exact payé dans un délai donné, nous devons utiliser une requête comme celle-ci :
SELECT SUM(sale.sale_amount_paid) AS amount_paid FROM sale WHERE sale.time_paid >= @start_time AND sale.time_paid <= @end_time;
La requête ci-dessous calculera le montant émis et payé dans une période de temps avec la date d'émission et la date de paiement cochées séparément :
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
Dans tous les exemples @start_time
et @end_time
sont des variables contenant l'heure de début et l'heure de fin de la période pour laquelle nous voulons vérifier la somme émise et payée.
Le tableau sale_item
relie les produits et les ventes. Bien sûr, nous devons supposer que nous aurons plusieurs éléments sur un reçu, nous avons donc besoin de cette table pour avoir une relation plusieurs à plusieurs.
Les attributs et leurs significations sont :
quantity_sold
– quantité de produit qui a été vendue et qui est facturée sur cette vente/reçu (par exemple, 3 cafés)price_per_unit
– même valeur queproduct.price_per_unit
au moment de la création de la vente. Nous devons l'enregistrer carprice_per_unit
dans leproduct
le tableau peut changer avec le tempsprice
– produit dequantity_sold
etprice_per_unit
; une petite redondance qui nous aide à éviter ce calcul dans les requêtes. Généralement, la somme de tous les prix des articles appartenant à la même vente doit être égale àsale.sale_amount
tax_amount
– montant de la taxe pour cet article à la réceptionsale_id
– identifiant de la vente à laquelle appartient cet articleproduct_id
– ID de produit lié à cet article
Nous pourrions maintenant facilement faire un rapport simple, combien de produits/services nous avons vendus au cours de la période et à quel prix.
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