配方问题

补课 2008-05-13 05:24:32
昨天四川汶川发生了7.8级的大地震,首先向罹难的同胞表示沉重哀悼,相信通过大家的努力,四川汶川地区的人民一定能度过难关,尽快重建家园.
好几天没有来这里和大家学习了,现在遇到一个关于配方的问题。

有一面包产品的配方如下:

面包: 1、糖 2、盐 3、面包皮
面包皮: 1、油 2、甜面团
甜面团: 1、面粉 2、水

现要求计算生产N个面包所用的最终材料数。

本人设计如下:


create table TBomHeader
(
id int,
bomName varchar(100),
Category varchar(100)
)

create table TBomItem
(
id int,
bomid int,
ItemName varchar(100),
UsingQty int
)


insert into TBomHeader
select 1,'面包','成品' union
select 2,'面包皮','半成品' union
select 3,'面团','半成品'

insert into TBomItem
select 1,1,'糖',10 union
select 2,1,'盐',5 union
select 3,1,'面包皮',10 union
select 4,2,'水',1 union
select 5,2,'面团',2 union
select 6,3,'面粉',3 union
select 7,3,'油',2

---------- 想得到的结果是
boName category ItemName UsingQty
面包 成品 糖 10
面包 成品 盐 5
面包 成品 水 10
面包 成品 面粉 6
面包 成品 油 4



请问有什么好的方法可以查询出来,或者更好的存储表设计,先谢谢大家了!!
...全文
207 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Limpire 2008-05-14
  • 打赏
  • 举报
回复
-->2000
declare @Level int
set @Level=0
select a.bomName as Name, a.*, b.ItemName, b.UsingQty, Level=@Level into # from TBomHeader a join TBomItem b on a.id=b.bomid where a.Category='成品'
while @@rowcount>0
begin
set @Level=@Level+1
insert # select b.Name, a.*, c.ItemName, b.UsingQty*c.UsingQty, @Level from TBomHeader a join # b on a.bomName=b.ItemName join TBomItem c on a.id=c.bomid where b.Level=@Level-1
end

select
Name as bomName,
'成品' as Category,
ItemName,
sum(UsingQty) as UsingQty
from #
where not exists (select 1 from TBomHeader where bomName=#.ItemName)
group by Name, ItemName
补课 2008-05-14
  • 打赏
  • 举报
回复
确实很油!!
Limpire 2008-05-13
  • 打赏
  • 举报
回复
这面包太油了
Limpire 2008-05-13
  • 打赏
  • 举报
回复
create table TBomHeader
(
id int,
bomName varchar(100),
Category varchar(100)
)

create table TBomItem
(
id int,
bomid int,
ItemName varchar(100),
UsingQty int
)

insert into TBomHeader
select 1,'面包','成品' union
select 2,'面包皮','半成品' union
select 3,'面团','半成品'

insert into TBomItem
select 1,1,'糖',10 union
select 2,1,'盐',5 union
select 3,1,'面包皮',10 union
select 4,2,'水',1 union
select 5,2,'面团',2 union
select 6,3,'面粉',3 union
select 7,3,'油',2

;
with T as
(
select a.bomName as Name, a.*, b.ItemName, b.UsingQty from TBomHeader a join TBomItem b on a.id=b.bomid where a.Category='成品'
union all
select b.Name, a.*, c.ItemName, b.UsingQty*c.UsingQty from TBomHeader a join T b on a.bomName=b.ItemName join TBomItem c on a.id=c.bomid
)
select
Name as bomName,
'成品' as Category,
ItemName,
sum(UsingQty) as UsingQty
from T
where not exists (select 1 from TBomHeader where bomName=T.ItemName)
group by Name, ItemName

/*
---------- 想得到的结果是
boName category ItemName UsingQty
面包 成品 糖 10
面包 成品 盐 5
面包 成品 水 10
面包 成品 面粉 6
面包 成品 油 4
*/

/*
---------- 实际到的结果是
boName category ItemName UsingQty
面包 成品 糖 10
面包 成品 盐 5
面包 成品 水 10
面包 成品 面粉 60 --> 每份面包10份面包皮 --> 每份面包皮2份面团 --> 每份面团3份面粉
面包 成品 油 40 --> 每份面包10份面包皮 --> 每份面包皮2份面团 --> 每份面团2份油
*/
-晴天 2008-05-13
  • 打赏
  • 举报
回复
前面少加了团:
create function dbo.zhaomianbao
(@bao decimal(5,2),@pi decimal(5,2),@tuan decimal(5,2))--输入现有多少包,多少皮,多少团 皮,团是生产过程中剩下的
returns
as
begin
declare @yuanliao table (tang decimal(5,2),yan decimal(5,2),you decimal(5,2),fen decimal(5,2),shui decimal(5,2))
declare @tuan_fen decimal(5,2),@tuan_shui decimal(5,2)
declare @pi_you decimal(5,2),@pi_tuan decimal(5,2)
declare @bao_tang decimal(5,2),@bao_yan decimal(5,2),@bao_pi decimal(5,2)

declare @tmp_tuan decimal(5,2),@tmp_pi decimal(5,2)

select @tuan_fen=0.3,@tuan_shui=0.7 --团的组成
select @pi_you=0.05,@pi_tuan=0.95 --皮的组成
select @bao_tang=0.05,@bao_yan=0.03,@bao_pi=0.92 --包的组成

set @tmp_pi=@bao * @bao_pi+@pi
set @tmp_tuan=@tmp_pi * @pi_tuan +@tuan

insert into @yuanliao
select @bao * @bao_tang,
@bao * @bao_yan,
@tmp_pi * @pi_you,
@tmp_tuan * @tuan_fen,
@tmp_tuan * @tuan_shui

select * from @yuanliao
end
-晴天 2008-05-13
  • 打赏
  • 举报
回复
用得着动用数据库么?

create function dbo.zhaomianbao
(@bao decimal(5,2),@pi decimal(5,2),@tuan decimal(5,2))--输入现有多少包,多少皮,多少团 皮,团是生产过程中剩下的
returns
as
begin
declare @yuanliao table (tang decimal(5,2),yan decimal(5,2),you decimal(5,2),fen decimal(5,2),shui decimal(5,2))
declare @tuan_fen decimal(5,2),@tuan_shui decimal(5,2)
declare @pi_you decimal(5,2),@pi_tuan decimal(5,2)
declare @bao_tang decimal(5,2),@bao_yan decimal(5,2),@bao_pi decimal(5,2)

declare @tmp_tuan decimal(5,2),@tmp_pi decimal(5,2)

select @tuan_fen=0.3,@tuan_shui=0.7 --团的组成
select @pi_you=0.05,@pi_tuan=0.95 --皮的组成
select @bao_tang=0.05,@bao_yan=0.03,@bao_pi=0.92 --包的组成

set @tmp_pi=@bao * @ bao_pi+@pi
set @tmp_tuan=@tmp_pi * @pi_tuan

insert into @yuanliao
select @bao * @bao_tang,
@bao * @bao_yan,
@tmp_pi * @pi_you,
@tmp_tuan * @tuan_fen,
@tmp_tuan * @tuan_shui

select * from @yuanliao
end
-狙击手- 2008-05-13
  • 打赏
  • 举报
回复
create table TBomHeader
(
id int,
bomName varchar(100),
Category varchar(100)
)

create table TBomItem
(
id int,
bomid int,
ItemName varchar(100),
UsingQty int
)


insert into TBomHeader
select 1,'面包','成品' union
select 2,'面包皮','半成品' union
select 3,'面团','半成品'

insert into TBomItem
select 1,1,'糖',10 union
select 2,1,'盐',5 union
select 3,1,'面包皮',10 union
select 4,2,'水',1 union
select 5,2,'面团',2 union
select 6,3,'面粉',3 union
select 7,3,'油',2
go


select cast(a.bomname as varchar),cast(c.itemname as varchar),c.UsingQty
from (
select bomName from TBomHeader where Category = '成品') a

full join

(select * from TBomItem a
where exists(select 1 from TBomHeader b where id = a.bomid )
and not exists(select 1 from TBomHeader where bomName = a.ItemName)) c
on 1 =1


drop table TBomHeader,TBomItem

/*
UsingQty
------------------------------ ------------------------------ -----------
面包 糖 10
面包 盐 5
面包 水 1
面包 面粉 3
面包 油 2

(所影响的行数为 5 行)
*/
kylike 2008-05-13
  • 打赏
  • 举报
回复

由于面包最终的成份落到粮、盐、油、面粉、水。
所以,此题可以如此设计:
1,设一个面包成份参数表,表字段为:面包、糖含量、盐含量、油含量、面粉含量、水含量。
根据面包实际成份写入数据。

2,假设现在做100个面包,查询结果时用以下语法
Select 100 as 面包个数, N'糖' as ItemName, 100*糖含量 as UsingQty From 参数表
Union
Select 100 as 面包个数, N'盐' as ItemName, 100*盐含量 as UsingQty From 参数表
Union
Select 100 as 面包个数, N'油' as ItemName, 100*油含量 as UsingQty From 参数表
Union
Select 100 as 面包个数, N'面粉' as ItemName, 100*面粉含量 as UsingQty From 参数表
Union
Select 100 as 面包个数, N'水' as ItemName, 100*水含量 as UsingQty From 参数表

这是我的设计思路。在查询结果时也可将语句封装成函数,每次调用函数就可得出结果。


补课 2008-05-13
  • 打赏
  • 举报
回复
吃饭去了。回头再聊。
-狙击手- 2008-05-13
  • 打赏
  • 举报
回复
有点bom样
补课 2008-05-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 Limpire 的回复:]
如果你这个配方只是“面包”的配方,我无话说
[/Quote]

不只是面包的,为什么会有这样的感叹呢,小楼?
Limpire 2008-05-13
  • 打赏
  • 举报
回复
如果你这个配方只是“面包”的配方,我无话说
补课 2008-05-13
  • 打赏
  • 举报
回复
先谢谢大家的热心帮助,可能是我没有讲清楚,
一级:面包=糖+盐+面包皮
二级:面包=糖+盐+水+甜面团
最终材料: 面包=糖+盐+水+面粉+油

其中 : 面包皮,甜面团都是中其配方。

现在先看看老乌龟的.

dobear_0922 2008-05-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 Limpire 的回复:]
似乎忽悠了一个问题,两个表没有体现出“面包”是由“面包皮”+“面团”组成的。
[/Quote]
就是,面包=糖+盐+面包皮 + 甜面团
Limpire 2008-05-13
  • 打赏
  • 举报
回复
逻辑环节缺失,没办法计算。
dawugui 2008-05-13
  • 打赏
  • 举报
回复
产品配件清单查询示例(邹建)
CREATE TABLE Item(ID int,Name varchar(10),Wast decimal(2,2))
INSERT Item SELECT 1,N'A产品',0.01
UNION ALL SELECT 2,N'B产品',0.02
UNION ALL SELECT 3,N'C产品',0.10
UNION ALL SELECT 4,N'D配件',0.15
UNION ALL SELECT 5,N'E物料',0.03
UNION ALL SELECT 6,N'F物料',0.01
UNION ALL SELECT 7,N'G配件',0.02

CREATE TABLE Bom(ItemID int,ChildId int)
INSERT Bom SELECT 1,4
UNION ALL SELECT 1,7 --A产品由D配件和G配件组成
UNION ALL SELECT 2,1
UNION ALL SELECT 2,6
UNION ALL SELECT 2,7 --B产品由F物料及G配件组成
UNION ALL SELECT 4,5
UNION ALL SELECT 4,6 --D配件由F物料组成
UNION ALL SELECT 3,2
UNION ALL SELECT 3,1 --C产品由A产品和B产品组成
GO

CREATE FUNCTION f_Bom(
@ItemIDs varchar(1000), --要查询物料清单及生产量的产品编号列表(逗号分隔)
@Num int --要生产的数量
)RETURNS @t TABLE(ItemID int,ChildId int,Nums int,Level int)
AS
BEGIN
DECLARE @Level int
SET @Level=1
INSERT @t SELECT a.ItemID,a.ChildId,ROUND(@Num/(1-b.Wast),0),@Level
FROM Bom a,Item b
WHERE a.ChildId=b.ID
AND CHARINDEX(','+RTRIM(a.ItemID)+',',','+@ItemIDs+',')>0
WHILE @@ROWCOUNT>0 and @Level<140
BEGIN
SET @Level=@Level+1
INSERT @t SELECT a.ItemID,b.ChildId,ROUND(a.Nums/(1-c.Wast),0),@Level
FROM @t a,Bom b,Item c
WHERE a.ChildId=b.ItemID
AND b.ChildId=c.ID
AND a.Level=@Level-1
END
RETURN
END
GO

--调用函数展开产品1、2、3的结构及计算生产10个产品时,各需要多少个配件
SELECT a.ItemID,ItemName=b.Name,
a.ChildId,ChildName=c.Name,
a.Nums,a.Level
FROM f_Bom('1,2,3',10) a,Item b,Item c
WHERE a.ItemID=b.ID
AND a.ChildId=c.ID
ORDER BY a.ItemID,a.Level,a.ChildId
Excel配方优化系统V2•2•3程氏完美修正版3.0   注意事项:   1.本系统目前仅支持excel2010及2007版本。   2.修复强制能量功能。   3.修复能量因子功能。   4.修正简化M7-M37,N7-N37单元格公式。    5.excel2010规划求解功能有新的变化。本系统在excel2010中运算时,   能量因子不可取0值,否则会出现二进制或alldierdent约束错误。   建议在无需使用能量因子时,将该取值与能量需要量手工同步。   本次修改记要:   1.增加系统对office2003的兼容支持。   2.增强系统运算原料种类完全支持数达到28种,营养指标完全支持数达到27种。   3.添加品名下拉菜单,实现多工厂功能。   4.修复营养素选择菜单,可以让使用者自行决定参算营养指标。   5.清理成品库即产品价格表。   6.增加生产通知单和配方报告项目输出量。   Excel配方优化系统V2•2•3程氏完美修正版,是本人在尤佩华老师的Excel配方优化系统V2•2•3基础之上修正的。   尤老师的系统本来很不错,我也一直在学习运用。但是网路上流传的该系统经本人实践证明存在BUG。比如饲料模板中   A6-F6的数据均参与了运算,而在生成生产通知单和配方报告时不能正常输出;计算模板复制时,在成品价格表中不能   正常输出。这两处BUG大大降低了该系统的实用性。   本人才疏学浅,本着实事求是的科学态度加以修正。   1. 修正原版中饲料模板A6-F6的数据运算后不能正常输出到生产通知单和配方报告的问题,重新编译了宏。   2. 修正原版中计算模板复制时在成品价格表中不能正常输出的问题,重新编译了宏。   3. 修正原版中一些需手动输入时间为自动输入,改写了函数。   4. 修改原版中一些菜单背景,使之更加醒目。   5. 增设原版中一些菜单,使操作更加便捷。   注:本系统知识产权属原作者所有。

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧