求教一个冗余表的查询问题(应该是符合2NF了吧,呵呵)

pgz_007 2008-09-11 03:07:21
最近在开发一个小型的物资管理软件,也就是入库、出库(包括领料和退料)几个功能。出库主要是下面两个表,一个是出库单单号登记表(A),另一个是出库详细材料明细表(B)。我把领料和退料放在出库表A表里面一起搞,通过一个标志位type来区分。

出库登记表(A):
出库单号(outbhid)、领用项目用途(xmbhid)、出库单类别(Type:0代表领料、1代表退料)

出库材料明细表(B):
出库单号(outbhid)、材料编号(clbhid)、出库数量(outnumber:正数代表领料、负数代表退料)

A:
L000001 XM000001 0 (登记1号领料单)
L000002 XM000002 0
T000001 L000002 1 (登记1号退料单,要跟领料单对应)

B:
L000002 材料1 10 (领10个)
L000002 材料2 18
T000001 材料1 -5 (退5个)

-----------------------------------------------
问题提出:
我想做项目XM000002的总用料情况的报表:
select clbhid,sum(outnumber) from B left join A on A.outbhid=B.outbhid where A.xmbhid='XM000002'

但这样不行,因为退料单对应的项目编号变成了某领料单号(L000002)而不是直接对应项目XM000002。请问这个问题能用一个sql语句搞定吗?
...全文
145 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
fg5885 2008-09-11
  • 打赏
  • 举报
回复
风过的~~~~~~~~~~
pgz_007 2008-09-11
  • 打赏
  • 举报
回复
真厉害,我明天去试一试。
-晴天 2008-09-11
  • 打赏
  • 举报
回复
create table A(outbhid varchar(10),xmbhid varchar(10),[type] int)
insert into A select 'L000001','XM000001',0
union all select 'L000002','XM000002',0
union all select 'T000001','L000002',1

create table B(outbhid varchar(10),clbhid nvarchar(10),outnumber int)
insert into B select 'L000002','材料1',10
union all select 'L000002','材料2',18
union all select 'T000001','材料1',-5
go
select t1.outbhid,t2.clbhid,t2.outnumber+isnull(t4.outnumber,0) as outnumbers
from A t1 inner join B t2 on t1.outbhid=t2.outbhid
left join A t3 on t3.outbhid=t1.xmbhid
left join B t4 on t4.outbhid=t3.outbhid
where t1.xmbhid='XM000002' and t1.[type]=0

go
drop table A,B
/*
outbhid clbhid outnumbers
---------- ---------- -----------
L000002 材料1 10
L000002 材料2 18

(2 行受影响)

*/
Garnett_KG 2008-09-11
  • 打赏
  • 举报
回复


SELECT B.clbhid,sum(b.outnumber)
FROM B INNER JOIN
(
SELECT outbhid FROM A WHERE Type=0 AND xmbhid='XM000002'
OR (
Type=1 AND EXISTS (
SELECT * FROM A as T
WHERE T.xmbhid=A.outbhid
)

) as Tmp
ON B.outbhid =Tmp.outbhid
GROUP BY B.clbhid

Garnett_KG 2008-09-11
  • 打赏
  • 举报
回复
没验证哦.

上面若有错,再试下这个.^_^


SELECT B.clbhid,sum(b.outnumber)
FROM B INNER JOIN
(
SELECT outbhid FROM A WHERE Type=0 AND xmbhid='XM000002'
OR (
Type=1 AND EXISTS (
SELECT * FROM A as T
WHERE T.xmbhid=A.outbhid
)

) as Tmp
ON B.outbhid =A.outbhid
GROUP BY B.clbhid



Garnett_KG 2008-09-11
  • 打赏
  • 举报
回复

在出库单登记表A中,
退料单号对应的是领料单,领料单才对应项目编号。所以你这样是不行的,你的不会让退料数和领料数相加。
>>>>

试下这个:




SELECT B.clbhid,sum(b.outnumber)
FROM B INNER JOIN A
ON B.outbhid =A.outbhid
WHERE A.xmbhid='XM000002'
OR
EXISTS(
SELECT *
FROM A as T
WHERE A.outbhid=T.xmbhid
AND A.xmbhid='XM000002'
)

GROUP BY B.clbhid

pgz_007 2008-09-11
  • 打赏
  • 举报
回复
在出库单登记表A中,
退料单号对应的是领料单,领料单才对应项目编号。所以你这样是不行的,你的不会让退料数和领料数相加。

[Quote=引用 4 楼 Garnett_KG 的回复:]
我想做项目XM000002的总用料情况的报表
>>>>

SQL code


SELECT B.clbhid,sum(b.outnumber)
FROM B INNER JOIN A
ON B.outbhid =A.outbhid
WHERE A.xmbhid='XM000002'
GROUP BY B.clbhid



[/Quote]
pgz_007 2008-09-11
  • 打赏
  • 举报
回复
开退料单的时候只能从其对应的某领料表的详细材料清单中退,不会超过领料数。

你说的那15个和 退料单所对应的领料单对应啊(T000001 L000002 1 )。退料对应领料,领料对应项目。

[Quote=引用 3 楼 qianjin036a 的回复:]
建议:
不要将领料单与退料单对应,那会很麻烦的!
比如,你领了100个A,而后又领了80个A,最后退掉15个A,你说这15个应该与哪次领料对应?
材料表以材料编号为主键.
领料表以材料编号为外键.
增加一个项目表,在领料单上填上对应的项目编号就行了.
[/Quote]
pgz_007 2008-09-11
  • 打赏
  • 举报
回复
我是楼主,因为数据量不是很大,所以这个冗余也没关系。

退料单对应的是L000002号领料单啊

[Quote=引用 1 楼 qianjin036a 的回复:]
L000001  XM000001  0  (登记1号领料单)
L000002  XM000002  0
T000001  L000002  1  (登记1号退料单,要跟领料单对应)

这里与1号领料单对应了吗?
[/Quote]
-晴天 2008-09-11
  • 打赏
  • 举报
回复
材料表
编号 材料名称 型号 规格 单位 库存数量 单价

项目表
项目编号 项目名称

领料表
编号 材料编号 项目编号 数量 标记

统计项目所领用的所有材料:
select a.项目名称,b.材料名称,sum(c.数量*标记)
from 领料表 c inner join 项目表 a on a.项目编号=c.项目编号
inner join 材料表 b on b.材料编号=c.材料编号
where a.项目编号='XM00001'
group by a.项目名称,b.材料名称
Garnett_KG 2008-09-11
  • 打赏
  • 举报
回复
我想做项目XM000002的总用料情况的报表
>>>>



SELECT B.clbhid,sum(b.outnumber)
FROM B INNER JOIN A
ON B.outbhid =A.outbhid
WHERE A.xmbhid='XM000002'
GROUP BY B.clbhid

-晴天 2008-09-11
  • 打赏
  • 举报
回复
建议:
不要将领料单与退料单对应,那会很麻烦的!
比如,你领了100个A,而后又领了80个A,最后退掉15个A,你说这15个应该与哪次领料对应?
材料表以材料编号为主键.
领料表以材料编号为外键.
增加一个项目表,在领料单上填上对应的项目编号就行了.
utpcb 2008-09-11
  • 打赏
  • 举报
回复
你这样设计不是太好吧感觉
-晴天 2008-09-11
  • 打赏
  • 举报
回复
L000001 XM000001 0 (登记1号领料单)
L000002 XM000002 0
T000001 L000002 1 (登记1号退料单,要跟领料单对应)

这里与1号领料单对应了吗?

34,837

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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