我正在设计销售点“POS”数据库,同时使用MySQL作为我的DBMS。
将产品添加到产品数据库时,我添加了产品名称(即“Coca-Cola 2.L”)和UPC代码,成本,价格,部门,供应商和数量。
因此,如果我收到1000瓶的订单,每瓶花费1美元
然后让我们说在未来2个月,我只剩下100瓶现货“我的成本为100美元”。现在,我订购了5000瓶以上,但这次是因为我订购了5000瓶,供应商每瓶给我0.10美元(即每件0.90美元的成本。)所以,我的第二笔订单的成本是4500美元。我想确保我非常准确地追踪我的利润。因此,我以1美元购买的100美元我希望能够以1美元的成本和新的订单以0.90美元的成本单独跟踪这些。
我目前跟踪每个销售商品的成本的方式,通过从产品表中读取当前成本,并将其与sales_transactions_items表以及售价,transaction_id和product_id一起保存。
我现在遇到的问题是,当我收到5000瓶时,我将成本从1美元改为0.90美元,这使我的利润上升了(100瓶x每瓶0.10美元)100x0.10 = 10美元的利润我实际上没有获利。出售数量后,出现这种差异是因为数量达到了5100瓶,其中100件以1美元购买,5,000件以0.90美元购买。
我的问题:如何解决这个问题,我可以真实地捕捉到每件物品花费了多少钱。
答案 0 :(得分:2)
这是一个足够通用但过于简单的示例,说明了您的架构的外观
CREATE TABLE products
(
`id` int not null auto_increment primary key,
`name` varchar(13),
`price` decimal(12, 2), -- current sale price. You might want to extract it into it's own table `prices`
...
);
CREATE TABLE orders
(
`id` int not null auto_increment primary key,
`date` date,
...
);
CREATE TABLE order_items
(
`id` int not null auto_increment primary key,
`order_id` int not null,
`product_id` int,
`quantity` decimal(12, 3),
`cost` decimal(12, 2),
foreign key (`order_id`) references orders (id),
foreign key (`product_id`) references products (id)
);
CREATE TABLE sales
(
`id` int not null auto_increment primary key,
`date` datetime,
...
);
CREATE TABLE sale_items
(
`id` int not null auto_increment primary key,
`sale_id` int not null,
`product_id` int,
`quantity` decimal(12, 3),
`price` decimal(12, 2),
foreign key (`sale_id`) references sales (id),
foreign key (`product_id`) references products (id)
);
这是 SQLFiddle 演示
这使您能够独立跟踪成本和销售额。
计算总销售额,实际总成本和每件产品保证金的一种方法
SELECT product_id, p.name, sales_quantity, sales_total, cost_total, sales_total - cost_total margin
FROM
(
SELECT product_id, sales_quantity, sales_total, SUM(
CASE WHEN sales_quantity >= running_quantity
THEN cost * quantity
WHEN sales_quantity BETWEEN running_quantity - quantity AND running_quantity
THEN cost * (sales_quantity - (running_quantity - quantity))
ELSE 0
END) cost_total
FROM
(
SELECT s.*, o.cost, o.quantity, o.running_quantity
FROM
(
SELECT product_id,
SUM(quantity * price) sales_total,
SUM(quantity) sales_quantity
FROM sale_items
GROUP BY product_id
) s JOIN
(
SELECT product_id, cost, quantity, (
SELECT SUM(quantity)
FROM order_items
WHERE product_id = i.product_id
AND order_id <= i.order_id
) running_quantity
FROM order_items i
) o
ON s.product_id = o.product_id
) q
GROUP BY product_id, sales_quantity, sales_total
) q JOIN products p
ON q.product_id = p.id
示例输出:
| PRODUCT_ID | NAME | SALES_QUANTITY | SALES_TOTAL | COST_TOTAL | MARGIN | |------------|---------------|----------------|-------------|------------|--------| | 1 | Coca-Cola 2.L | 150 | 187.5 | 145 | 42.5 |
这是 SQLFiddle 演示
你可能会看到,在这个例子中,150个售出的100瓶装100美元(1美元* 100美元),其余50个售价45美元(0.9 * 50)
答案 1 :(得分:0)
Declare @FromDate DateTime=GetDate()
declare @ToDate DateTime=GetDate()
Select ToDateProfit.ProductID,ToDateProfit.Name,ToDateProfit.sales_quantity- ISNULL(FromDateProfit.sales_quantity,0) as Sales_Quantity
,ToDateProfit.sales_total-ISNULL(FromDateProfit.sales_total,0) as Sales_Total
,ToDateProfit.cost_total-ISNULL(FromDateProfit.cost_total,0) as Cost_Total
,ToDateProfit.margin-ISNULL(FromDateProfit.margin,0) as Margin
From
(
SELECT P.ProductID, p.name, sales_quantity, sales_total, cost_total, sales_total - cost_total margin
FROM
(
SELECT productid, sales_quantity, sales_total, SUM(
CASE WHEN sales_quantity >= running_quantity
THEN PurchasePrice* quantity
WHEN sales_quantity BETWEEN running_quantity - quantity AND running_quantity
THEN PurchasePrice * (sales_quantity - (running_quantity - quantity))
ELSE 0
END) cost_total
FROM
(
SELECT s.*, o.PurchasePrice, o.quantity, o.running_quantity
FROM
(
SELECT ProductID,
SUM((quantity * UnitPrice)/ExchangeRate) sales_total,
SUM(quantity) sales_quantity
FROM SaleDetail
Inner Join Sale on Sale.SaleID=SaleDetail.SaleID
where Convert(Date,Sale.SaleDate)<=Convert(date,@ToDate) --(must minus saledate <FromDate (GetDate() is ToDate) )
GROUP BY ProductID
) s JOIN
(
SELECT productid, BuyingPrice/ExchangeRate as PurchasePrice, quantity, (
SELECT SUM(quantity)
FROM PurchaseDetail
inner join Purchase Pur on Pur.PurchaseID=PurchaseDetail.PurchaseID
WHERE productid = i.productid
AND Pur.Date <= PurI.date ----Fifo (if want lifo change <= to >=)
) running_quantity
FROM PurchaseDetail i
Inner join Purchase PurI on PurI.PurchaseID=i.PurchaseID
) o
ON s.productid = o.productid
)q
GROUP BY productid, sales_quantity, sales_total
) q JOIN product p
ON q.ProductID = p.ProductID
)ToDateProfit
Left Join
(
SELECT P.ProductID, p.name, sales_quantity, sales_total, cost_total, sales_total - cost_total margin
FROM
(
SELECT productid, sales_quantity, sales_total, SUM(
CASE WHEN sales_quantity >= running_quantity
THEN PurchasePrice* quantity
WHEN sales_quantity BETWEEN running_quantity - quantity AND running_quantity
THEN PurchasePrice * (sales_quantity - (running_quantity - quantity))
ELSE 0
END) cost_total
FROM
(
SELECT s.*, o.PurchasePrice, o.quantity, o.running_quantity
FROM
(
SELECT ProductID,
SUM((quantity * UnitPrice)/ExchangeRate) sales_total,
SUM(quantity) sales_quantity
FROM SaleDetail
Inner Join Sale on Sale.SaleID=SaleDetail.SaleID
where Convert(Date,Sale.SaleDate)<Convert(date,@FromDate) --(must minus saledate <FromDate (GetDate() is ToDate) )
GROUP BY ProductID
) s JOIN
(
SELECT productid, BuyingPrice/ExchangeRate as PurchasePrice, quantity, (
SELECT SUM(quantity)
FROM PurchaseDetail
inner join Purchase Pur on Pur.PurchaseID=PurchaseDetail.PurchaseID
WHERE productid = i.productid
AND Pur.Date <= PurI.date ----Fifo (if want lifo change <= to >=)
) running_quantity
FROM PurchaseDetail i
Inner join Purchase PurI on PurI.PurchaseID=i.PurchaseID
) o ON s.productid = o.productid
) q
GROUP BY productid, sales_quantity, sales_total
) q JOIN product p
ON q.ProductID = p.ProductID
)FromDateProfit on FromDateProfit.ProductID=ToDateProfit.ProductID
Inner Join ---------Only Product
(
Select Product.ProductID From Product
Inner Join SaleDetail On SaleDetail.ProductID=Product.ProductID
Inner Join Sale On Sale.SaleID=SaleDetail.SaleID
Where CONVERT(Date,SaleDate)>=CONVERT(Date,@FromDate) And CONVERT(Date,SaleDate)<=CONVERT(Date,@ToDate)
Group By Product.ProductID)SP On SP.ProductID=ToDateProfit.ProductID
答案 2 :(得分:0)
“我想确保我非常准确地追踪我的利润。因此,我以1美元购买的100美元我希望能够以1美元的成本和新的订单以0.90美元的成本单独跟踪这些。” - 这不是必需的。您必须计算当前平均价格并使用它计算利润。您没有每个瓶子的序列号,因此即使您想知道每个项目的利润 - 您也无法做到。从业主的角度来看,重要的是要知道可口可乐的总利润,而不是“从这个瓶子里得到0.50,从那瓶子里得到0.45”。