建议:
入库清单表,领料清单表 增加 日期 字段,可以有效减少服务器 根据日期段的统计 的运算量。
另外,奇怪表结构这么精炼,怎么存在 材料名 这样的字段?为什么不用 材料信息 表 里面的 编码?
还有 存在 金额 字段?(万一 数量*单价 <> 金额,以哪个为准?)select 材料名,采购数量,采购金额,领用数量,实领数量,领用金额
from
((select * from
(select a.名称及规格 as 材料名,isnull(sum(b.数量),0) as 采购数量,isnull(sum(b.数量*b.单价),0) as 采购金额 
from 材料信息 a,入库清单 b
where b.材料名=a.名称及规格 and b.单号 in (select 单号 from 入库表 where 采购日期>=:date1 and 采购日期<=:date2))c
left join 
(select d.材料名,sum(d.领料数量) as 领料数量,sum(d.实领数量) as 实领数量,sum(d.金额) as 领料金额 from 领料清单 d where d.单号 in 
(select 单号 from 领料清单表 where 日期>=:date3 and 日期<=:date4)
group by d.材料名)e on e.材料名=c.材料名
)f
where f.采购数量<>0 or f.领用数量<>0

解决方案 »

  1.   

    入库表:单号,采购日期,经手人,总金额,备注。 
    入库清单表:单号,材料名,单位,数量,单价,金额。  领料单:单号,日期,工程地点,用途,经手人,领料师傅,工程部门,总金额,备注。 
    领料清单表:单号,材料名,单位,领料数量,实领数量,金额。  材料信息:编码,名称及规格,用途,单位,单价,备注。 这个是表结构 
    请大家帮帮忙!!!我想求出所有材料一个月内的购入和领用情况 
    ============================================================
    一条语句是可以搞定的.如果用前台做的话,当库存上一定量的时候,非常非常的慢的.
     材料名 是否就是 材料信息 表中的编码 ?? 各表字段名称不一致,写SQL非累死你不可.
     下面没有测试,你改改.
    SELECT TBB1.*,TAB2.*,TAB3.* FROM

    SELECT 材料名,SUM(数量),SUM(金额) FROM (
         SELECT B.材料名,B.数量,B.金额 FROM 入库表 AS A INNER JOIN 入库清单表 AS B ON A.单号=B.单号
         WHERE A.采购日期 BETWEEN '开始日期' AND '结束日期'
    ) AS T1 GROUP BY 材料名 )  AS TAB1
    INNER JOIN 
    (
    SELECT 材料名,SUM(领料数量),SUM(实领数量),SUM(金额) FROM (
         SELECT B.材料名,B.领料数量,B.实领数量,B.金额 FROM 领料单 AS A INNER JOIN 领料清单表 AS B ON A.单号=B.单号
         WHERE A.日期 BETWEEN '开始日期' AND '结束日期'
    ) AS T1 GROUP BY 材料名 ) AS TAB2 ON TAB1.材料名=TAB2.材料名
    INNER JOIN 材料信息 AS TAB3 ON TAB1.编码=TAB3.材料名
      

  2.   

    :) 那将 INNER JOIN 改为 FULL JOIN 
    ------------------------------------------------
    SELECT TBB1.*,TAB2.*,TAB3.* FROM 
    (  
    SELECT 材料名,SUM(数量),SUM(金额) FROM ( 
         SELECT B.材料名,B.数量,B.金额 FROM 入库表 AS A INNER JOIN 入库清单表 AS B ON A.单号=B.单号 
         WHERE A.采购日期 BETWEEN '开始日期' AND '结束日期' 
    ) AS T1 GROUP BY 材料名 )  AS TAB1 
    FULL JOIN  

    SELECT 材料名,SUM(领料数量),SUM(实领数量),SUM(金额) FROM ( 
         SELECT B.材料名,B.领料数量,B.实领数量,B.金额 FROM 领料单 AS A INNER JOIN 领料清单表 AS B ON A.单号=B.单号 
         WHERE A.日期 BETWEEN '开始日期' AND '结束日期' 
    ) AS T1 GROUP BY 材料名 ) AS TAB2 ON TAB1.材料名=TAB2.材料名 
    INNER JOIN 材料信息 AS TAB3 ON TAB1.编码=TAB3.材料名
      

  3.   

    回:
    发表于:2008-05-03 09:26:3311楼 得分:0 
    谢谢这位仁兄! 真的麻烦你,我一定给你分,我已经借助编程语言用循环搞定了. 
    不过这位仁兄 你不感觉增加日期字段会有很多数据冗余吗?还有把材料名改为编码后会在程序设计中多一些查询语句吗? 1、建议增加日期字段,是我自己的经验之谈,每个人的做法都是不一样的。我是认为这样子做,空间开销不大,而特别在查大表的时候,显示出来的优势却是很惊人,才这样建议的。2、材料名之所以建议用编码,一方面是查询时匹配比较快,也节省空间;另一方面,也允许修改材料名,要不输入错误,要改材料名,岂不是整个表都得改?
    你说的没错,如果用编码,就要在sql语句里面增加匹配的语句,但是你站在编码的角度看,所有的东西都是一个个编号,计算统计查询都是按编码为准,在需要的时候 最后一步才加上 材料名,这样自己做什么都很清晰了。
      

  4.   

    Full join也不好吧?因为你用* 引用,后面的tab2的 材料名 字段的内容,也不会跑到 前面的 tab1的 材料名 的字段上啊?
      

  5.   

    Full join也不好吧?因为你用* 引用,后面的tab2的 材料名 字段的内容,也不会跑到 前面的 tab1的 材料名 的字段上啊? 
    ===============================
    不会 , :)
      

  6.   

    可以改个别名,或让某个表不显示也可以.
    用 INNER ,LEFT ,RIGHT 都不合理.只有FULL 唯一合理的.