Almacenar correctamente los datos de ventas y luego combinarlos puede conducir a la creación de un modelo predictivo con una alta tasa de precisión. En este y los próximos artículos analizaremos el diseño de una base de datos para registrar las ventas.
Todo el mundo vive vendiendo algo.
Robert Louis Stevenson
En el mundo actual, vender productos es omnipresente. Y los vendedores que tienen acceso a herramientas sólidas que aprovechan los datos históricos para analizar tendencias y permiten que una empresa ajuste las estrategias comerciales en consecuencia, tienen una ventaja sobre sus competidores. Hay muchos parámetros que pueden afectar los resultados de la empresa:la situación económica global actual, la ubicación de los clientes, la edad, el estado material y civil, y el historial de contactos previos o ventas a clientes.
Comenzaremos con un ejemplo muy simple:un modelo de base de datos para ventas en una cafetería . En artículos posteriores, extenderemos el modelo a la venta de productos en otras sucursales.
Modelo de Ventas
En este artículo, analizaremos solo una parte del modelo que contiene datos de ventas y faltan otras partes.
Todavía tenemos conexiones con las tablas que faltan y consideraremos el modelo como una caja negra, suponiendo que lo siguiente es correcto para la tabla sale
:
user_has_role_id
consulte la identificación enuser_has_role
(como se presentó en mi artículo anterior en la sección "Componente de tiempo agregado") y almacena información sobre el usuario que creó el registro de venta
Este modelo nos permite crear registros de ventas con múltiples artículos. Cada artículo está relacionado con un producto de nuestro catálogo. El momento en que generamos una venta puede ser diferente al momento en que se paga la venta. Por ejemplo, para una taza de café estos momentos diferirán en cuestión de minutos u horas. Si nuestra tienda vendió dispositivos de telecomunicaciones, la diferencia puede ser de unos días, tal vez incluso meses.
Mesas
Echemos un vistazo a la definición de la tabla y expliquemos el propósito y el uso de los atributos.
La tabla más importante del modelo es product
. Se utiliza para almacenar detalles sobre los productos que ofreceremos a nuestros clientes. Los productos generalmente se entregan a un cliente y se pagan una vez, generalmente en el momento de la entrega. Además, los productos suelen ser objetos físicos como automóviles, teléfonos, paquetes de azúcar o tazas de café.
Hablaremos sobre la venta de cosas no físicas (servicios) en los próximos artículos.
Atributos en el product
tabla son:
name
– el nombre del producto en el sistemaprice_per_unit
– coste del producto por unidad (p. ej., 1 taza de café cuesta 1,8 euros, 1 coche cuesta 17 500 euros, 1 kg de arroz cuesta 2 euros)basic_unit
– unidad base cuando vendemos un producto (p. ej., pieza, kg, litro)tax_percentage
– porcentaje del precio_por_unidad que se cobrará como impuesto. Debemos asumir que el porcentaje de impuestos no sería el mismo para todos los productoslimited
– este campo se establece en Verdadero si tenemos una cantidad limitada en stock y en Falso de lo contrario (por ejemplo, podemos pedir cualquier cantidad que necesitemos para nuestra tienda a un distribuidor)in_stock
– si limited=True, este atributo muestra cuántos tenemos disponibles para venderactive_for_sale
– si este atributo es falso, significa que actualmente no estamos ofreciendo ese producto a la venta; de lo contrario, podemos ofrecerlo a los clientes
Podemos obtener una lista de productos que podemos ofrecer a los clientes con la siguiente consulta:
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))
La tabla sale_status
es solo un diccionario simple que contiene todos los estados que una venta puede tener en el sistema (por ejemplo, "recibo emitido", "recibo pagado").
sale
es la segunda mesa más importante de este modelo. Hasta el momento, esta tabla no tiene conexión con los clientes a los que les vendimos productos porque, en nuestro ejemplo de cafetería, no necesitamos saber dicha información. En la parte 2, el modelo se ampliará para cubrir tales casos. Los atributos en la tabla y sus significados son:
time_created
– hora en que se generó un registro de venta en el sistema (por ejemplo, hora automática en que se creó el registro cuando generamos una venta de café en nuestra cafetería o una hora agregada manualmente si así lo deseamos)time_paid
– por lo general, podemos esperar que algunas ventas se paguen dentro de unos días o incluso un mes después de la creación (por ejemplo, si entregamos software y creamos un recibo, podemos esperar hasta 90 días para recibir el pago en algunos países, si todo va bien). la ley)sale_amount
– importe original que se pretende cobrar al clientesale_amount_paid
– cantidad que el cliente realmente pagó. Puede ser nulo porque en el momento en que creamos un recibo no siempre tenemos esta informacióntax_amount
– suma de todos los montos de impuestos por artículos en ese recibosale_status_id
– referencia asale_status
mesauser_has_role_id
– referencia al usuario y su función en el momento en que ingresó el recibo en el sistema
Podemos obtener el monto emitido y pagado (según time_created) dentro de un período de tiempo con una consulta como esta:
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;
Para obtener el monto exacto pagado dentro de un período de tiempo, debemos usar una consulta como esta:
SELECT SUM(sale.sale_amount_paid) AS amount_paid FROM sale WHERE sale.time_paid >= @start_time AND sale.time_paid <= @end_time;
La consulta a continuación calculará el monto emitido y pagado dentro de un período de tiempo con la fecha de emisión y la fecha de pago verificadas por separado:
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
En todos los ejemplos @start_time
y @end_time
son variables que contienen la hora de inicio y la hora de finalización del período para el que queremos verificar la SUM emitida y pagada.
La tabla sale_item
conecta productos y ventas. Por supuesto, debemos asumir que tendremos múltiples artículos en un recibo, por lo que necesitamos que esta tabla tenga una relación de muchos a muchos.
Los atributos y sus significados son:
quantity_sold
– cantidad de producto que se vendió y se carga en esa venta/recibo (por ejemplo, 3 cafés)price_per_unit
– mismo valor queproduct.price_per_unit
en el momento en que se creó la venta. Tenemos que guardarlo porqueprice_per_unit
en elproduct
la tabla puede cambiar con el tiempoprice
– producto dequantity_sold
yprice_per_unit
; una pequeña redundancia que nos ayuda a evitar este cálculo en las consultas. Generalmente, la suma de los precios de todos los artículos pertenecientes a la misma venta debe ser igual asale.sale_amount
tax_amount
– monto del impuesto por ese artículo en el recibosale_id
– ID de venta a la que pertenece este artículoproduct_id
– ID de producto relacionado con este artículo
Ahora podríamos hacer fácilmente un informe simple, cuántos productos/servicios vendimos en el período y a qué precio.
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