英文:
mysql calculating to get profit or loss from 2 tables ( Purchases and Sales) in FIFO mode
问题
如何从这两个表中计算利润或损失?
需要将购买表中每个物品的成本,按照以下方式计算:(销售价格 * 数量) - (成本价格 * 数量) 作为利润/损失。
id | 物品编号 | 数量 | 价格 | 成本 | 利润 |
---|---|---|---|---|---|
1 | 1 | 2 | 25 | 40 | 10 |
2 | 2 | 3 | 15 | 30 | 15 |
3 | 1 | 3 | 26 | 60 | 18 |
4 | 1 | 2 | 22 | 40 | 4 |
不知道如何操作吗?目前我正在使用PHP,但花费太多时间。
英文:
how to calculate profit or loss from the 2 tables?
create table items(id int primary key auto_increment, name varchar(255));
insert into items value(null,'A');
insert into items value(null,'B');
insert into items value(null,'C');
insert into items value(null,'D');
id | name |
---|---|
1 | A |
2 | B |
3 | C |
4 | D |
create table purchase(id int primary key auto_increment, item_id int,qnt int,price int);
insert into purchase value(null,1,10,20);
insert into purchase value(null,2,10,22);
insert into purchase value(null,3,10,25);
insert into purchase value(null,4,10,18);
insert into purchase value(null,5,10,25);
id | ittem_id | qnt | cost |
---|---|---|---|
1 | 1 | 10 | 20 |
2 | 2 | 10 | 10 |
3 | 3 | 10 | 10 |
4 | 4 | 10 | 10 |
5 | 1 | 10 | 25 |
6 | 2 | 10 | 16 |
create table sales(id int primary key auto_increment, item_id int,qnt int,price int);
insert into purchase value(null,1,2,25);
insert into purchase value(null,2,3,15);
insert into purchase value(null,1,3,26);
insert into purchase value(null,1,2,22);
id | ittem_id | qnt | price |
---|---|---|---|
1 | 1 | 2 | 25 |
2 | 2 | 3 | 15 |
3 | 1 | 3 | 26 |
4 | 1 | 2 | 22 |
what I need is to put the cost of each item from the purchase table like this,(salespriceqnt)-( costpriceqnt) as profit/loss
id | ittem_id | qnt | price | cost | profit |
---|---|---|---|---|---|
1 | 1 | 2 | 25 | 40 | 10 |
2 | 2 | 3 | 15 | 30 | 15 |
3 | 1 | 3 | 26 | 60 | 18 |
4 | 1 | 2 | 22 | 40 | 4 |
no idea how to do it, right now I am doing this with PHP which takes too much time.
答案1
得分: 0
以下是已翻译的代码部分:
select items.name as item, coalesce(sales_totals.total, 0) as total_sales, coalesce(purchases_totals.total, 0) as total_purchases, coalesce(sales_totals.total, 0) - coalesce(purchases_totals.total, 0) as profit
from items
left join
(
select item_id, sum(qnt*price) as total
from purchase
group by item_id
) purchases_totals on purchases_totals.item_id = items.id
left join
(
select item_id, sum(qnt*price) as total
from sales
group by item_id
) sales_totals on sales_totals.item_id = items.id;
This will yield the below output
| item | total_sales | total_purchases | profit |
|:----:|:-----------:|:---------------:|:------:|
| A | 172 | 200 | -28 |
| B | 45 | 220 | -175 |
| C | 0 | 250 | -250 |
| D | 0 | 180 | -180 |
Some things to note
- Since this uses left joins to the purchases and sales tables based on the items table, and there are no 'E' items in the items table, it will not show any results for that item even if there are purchases or sales
- I have used a coalesce function on the subquery results in the outer select to allow records with no purchases or sales to return 'cleanly', ie, 0 instead of null
This can easily be expanded to include other calculations, as demonstrated below
select items.name as item, coalesce(sales_totals.total, 0) as total_sales, coalesce(purchases_totals.total, 0) as total_purchases, coalesce(sales_totals.total, 0) - coalesce(purchases_totals.total, 0) as profit, coalesce(purchases_totals.bought, 0) - coalesce(sales_totals.sold, 0) as stock_on_hand
from items
left join
(
select item_id, sum(qnt*price) as total, sum(qnt) as bought
from purchase
group by item_id
) purchases_totals on purchases_totals.item_id = items.id
left join
(
select item_id, sum(qnt*price) as total, sum(qnt) as sold
from sales
group by item_id
) sales_totals on sales_totals.item_id = items.id;
This adds in a a sum of 'qnt' in each of the subqueries which can then be subtracted in the parent query to provide a stock level
| item | total_sales | total_purchases | profit | stock_on_hand |
|:----:|:-----------:|:---------------:|:------:|:-------------:|
| A | 172 | 200 | -28 | 3 |
| B | 45 | 220 | -175 | 7 |
| C | 0 | 250 | -250 | 10 |
| D | 0 | 180 | -180 | 10 |
如您所要求,这是已翻译的代码部分,没有其他内容。
英文:
To directly answer your question as I understand it - this query should do the trick
select items.name as item, coalesce(sales_totals.total, 0) as total_sales, coalesce(purchases_totals.total, 0) as total_purchases, coalesce(sales_totals.total, 0) - coalesce(purchases_totals.total, 0) as profit
from items
left join
(
select item_id, sum(qnt*price) as total
from purchase
group by item_id
) purchases_totals on purchases_totals.item_id = items.id
left join
(
select item_id, sum(qnt*price) as total
from sales
group by item_id
) sales_totals on sales_totals.item_id = items.id;
This will yield the below output
item | total_sales | total_purchases | profit |
---|---|---|---|
A | 172 | 200 | -28 |
B | 45 | 220 | -175 |
C | 0 | 250 | -250 |
D | 0 | 180 | -180 |
Some things to note
- Since this uses left joins to the purchases and sales tables based on the items table, and there are no 'E' items in the items table, it will not show any results for that item even if there are purchases or sales
- I have used a coalesce function on the subquery results in the outer select to allow records with no purchases or sales to return 'cleanly', ie, 0 instead of null
This can easily be expanded to include other calculations, as demonstrated below
select items.name as item, coalesce(sales_totals.total, 0) as total_sales, coalesce(purchases_totals.total, 0) as total_purchases, coalesce(sales_totals.total, 0) - coalesce(purchases_totals.total, 0) as profit, coalesce(purchases_totals.bought, 0) - coalesce(sales_totals.sold, 0) as stock_on_hand
from items
left join
(
select item_id, sum(qnt*price) as total, sum(qnt) as bought
from purchase
group by item_id
) purchases_totals on purchases_totals.item_id = items.id
left join
(
select item_id, sum(qnt*price) as total, sum(qnt) as sold
from sales
group by item_id
) sales_totals on sales_totals.item_id = items.id;
This adds in a a sum of 'qnt' in each of the subqueries which can then be subtracted in the parent query to provide a stock level
item | total_sales | total_purchases | profit | stock_on_hand |
---|---|---|---|---|
A | 172 | 200 | -28 | 3 |
B | 45 | 220 | -175 | 7 |
C | 0 | 250 | -250 | 10 |
D | 0 | 180 | -180 | 10 |
I leave it as an exercise for the reader to further modify the query to calculate the value of the stock on hand, which to me would be the logical next addition
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论