插入带有运行余额的行

时间:2014-02-12 21:53:14

标签: php mysql sql select insert

我有一个包含这些列的简单库存数据库

mat_id    material_name     supplier    stock_in      stock_bal    date

如何添加具有相同材质名称的行,stock_in值将总计为stock_bal? 我需要选择吗? 我的第一个输入应该是:

mat_id    material_name     supplier    stock_in      stock_bal      date
1           paint            dummy         20            ?           feb13

问号应该生成stock_in总数为20.每次我使用相同的材​​料名称再次插入时,它应该总计先前的库存余额和新的stock_in,如:

mat_id    material_name     supplier    stock_in      stock_bal      date
1           paint            dummy         20            20           feb13
1           paint            dummy         10            30           feb13

我是否需要if / else我的插入查询? 请帮助。我只是个初学者

4 个答案:

答案 0 :(得分:0)

解决问题的最佳方法是在将数据库插入数据库之前计算应用程序级别的记录。

答案 1 :(得分:0)

获得累积总和的一种方法是使用子查询:

select i.*,
       (select sum(i2.stock_in)
        from inventory i2
        where i2.mat_id = i.mat_id and
              i2.date <= i.date
       ) as stock_bal
from inventory i;

这使用日期来订购记录。具有相同日期的记录将具有相同的stock_bal,因为数据没有其他列来区分具有相同日期的事物的顺序(例如自动递增/标识列)。

答案 2 :(得分:0)

我不确定你需要什么,但我会尝试解释: 如果在你的表格中,例如mat_id 1和3是完全相同的颜料(相同的品牌和EAN条形码),你的表格模型是不正确的,它最好是制作不同的表格(产品和供应商,第三个是参考哪些材料可以由供应商发送/哪个供应商可以发送产品和交付历史。

CREATE TABLE IF NOT EXISTS `DELIVERY_HISTORY` (
  `dh_id` int(11) NOT NULL AUTO_INCREMENT,
  `shm_id` int(11) NOT NULL,
  `delivery_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `stock_in` int(11) NOT NULL,
  PRIMARY KEY (`dh_id`),
  KEY `shm_id` (`shm_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `MATERIAL` (
  `material_id` int(11) NOT NULL AUTO_INCREMENT,
  `material_name` varchar(64) DEFAULT NULL,
  `stock_bal` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`material_id`),
  KEY `material_name` (`material_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `SUPPLIER` (
  `supplier_id` int(11) NOT NULL AUTO_INCREMENT,
  `supplier_name` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`supplier_id`),
  KEY `supplier_name` (`supplier_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `SUPPLIER_HAS_MATERIAL` (
  `shm_id` int(11) NOT NULL AUTO_INCREMENT,
  `supplier_id` int(11) NOT NULL,
  `material_id` int(11) NOT NULL,
  PRIMARY KEY (`shm_id`),
  KEY `supplier_id` (`supplier_id`,`material_id`),
  KEY `material_id` (`material_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

ALTER TABLE `DELIVERY_HISTORY`
  ADD CONSTRAINT `DELIVERY_HISTORY_ibfk_1` FOREIGN KEY (`shm_id`) REFERENCES `SUPPLIER_HAS_MATERIAL` (`shm_id`);

ALTER TABLE `SUPPLIER_HAS_MATERIAL`
  ADD CONSTRAINT `SUPPLIER_HAS_MATERIAL_ibfk_2` FOREIGN KEY (`material_id`) REFERENCES `MATERIAL` (`material_id`),
  ADD CONSTRAINT `SUPPLIER_HAS_MATERIAL_ibfk_1` FOREIGN KEY (`supplier_id`) REFERENCES `SUPPLIER` (`supplier_id`);

在这种情况下,您可以创建多个材料和供应商,参考哪个供应商提供的材料,或者只是列出供应商可以提供的所有产品,供应商交付的历史记录。

现在添加材料:

INSERT INTO `test`.`MATERIAL` (`material_id` , `material_name` , `stock_bal`) VALUES (NULL , 'paint', '0'), (NULL , 'bolt', '0');

添加供应商:

INSERT INTO `test`.`SUPPLIER` (`supplier_id` , `supplier_name`)
VALUES
(NULL , 'dummy'),
(NULL , 'test'),
(NULL , 'demo');

添加参考资料/供应商

INSERT INTO `SUPPLIER_HAS_MATERIAL`
(`shm_id`, `supplier_id`, `material_id`)
 VALUES 
(NULL, 1, 1),
(NULL, 2, 2),
(NULL, 3, 1);

显示一些utils查询: 列出所有材料和供应商:

SELECT m.material_name, s.supplier_name
FROM MATERIAL m, SUPPLIER s, SUPPLIER_HAS_MATERIAL shm
WHERE shm.supplier_id = s.supplier_id
AND shm.material_id = m.material_id

列出特定材料的所有供应商:

SELECT m.material_name, s.supplier_name
FROM MATERIAL m, SUPPLIER s, SUPPLIER_HAS_MATERIAL shm
WHERE shm.supplier_id = s.supplier_id
AND shm.material_id = m.material_id
AND m.material_id = 1

列出特定供应商的所有材料:

SELECT m.material_name, s.supplier_name
FROM MATERIAL m, SUPPLIER s, SUPPLIER_HAS_MATERIAL shm
WHERE shm.supplier_id = s.supplier_id
AND shm.material_id = m.material_id
AND s.supplier_id = 1

显示产品库存:

SELECT m.material_name, m.stock_bal
FROM MATERIAL m
WHERE m.material_id = 1

如果你使用PHP,我想你知道stock_in,供应商和材料的价值。

在SUPPLIER_HAS_MATERIAL中找到物料/供应商的ID(material_id = 1:paint; supplier_id = 1:dummy)

SELECT shm.shm_id
FROM MATERIAL m, SUPPLIER s, SUPPLIER_HAS_MATERIAL shm
WHERE shm.supplier_id = s.supplier_id
AND shm.material_id = m.material_id
AND m.material_id =1
AND s.supplier_id =1

在我的情况下shm_id = 1.现在是时候添加一个交货(stock_in = 20):

INSERT INTO `test`.`DELIVERY_HISTORY` (
`dh_id` , `shm_id` , `delivery_date` , `stock_in`
)
VALUES (
NULL , 1, CURRENT_TIMESTAMP , 20
)

现在更新物料stock_bal,物料油漆的stock_in(20)值(material_id = 1)

UPDATE MATERIAL
SET stock_bal = (stock_bal + 20)
WHERE material_id = 1

注意在PHP中,您可以在INSERT之后检查mysqli_insert_id函数的值。如果值> 0然后INSERT正确完成,否则您可以编写回退例程。

您现在可以检查paint stock_bal的值。

以下是完成测试用例的最后一次INSERT和UPDATE,但不要忘记使用之前的select来了解我是如何获得shm_id的:

-- shm_id = 2 : material_id = 2 (bolt) / supplier_id = 2 (test)
-- Adding 10 bolt
INSERT INTO `test`.`DELIVERY_HISTORY` (
`dh_id` , `shm_id` , `delivery_date` , `stock_in`
)
VALUES (
NULL , 2, CURRENT_TIMESTAMP , 10
);
UPDATE MATERIAL
SET stock_bal = (stock_bal + 10)
WHERE material_id = 2;
-- CHECK YOUR MATERIAL stock_bal
-- shm_id = 3 : material_id = 1 (paint) / supplier_id = 3 (demo)
-- Adding 10 paint
INSERT INTO `test`.`DELIVERY_HISTORY` (
`dh_id` , `shm_id` , `delivery_date` , `stock_in`
)
VALUES (
NULL , 2, CURRENT_TIMESTAMP , 10
);
UPDATE MATERIAL
SET stock_bal = (stock_bal + 10)
WHERE material_id = 1;
-- CHECK YOUR MATERIAL stock_bal

我希望这个解释能帮到你(如果我能正确理解你的问题)。

答案 3 :(得分:0)

SELECT&#39; mat_id&#39;,&#39; material_name&#39;,&#39; supplier&#39;,&#39; stock_in&#39;,
       @running_bal:= @running_bal +(&#39; stock_in&#39;)as&#39; stock_bal&#39;,date FROM YourtableName,(SELECT @running_bal:= 0)tempName