当前位置:主页>仓库管理软件> 列表

SQL我认为不简单的一个问题

销售管理软件版1楼: 有如下四个表
Table1 单据工序明细
 Table2 单据产品明细

 Table3 产品资料表
 Table4 产品定额表

以下是各表的结构

 Table1(单据工序明细)
===========================================================
PO_ID(单据编号) WW_ID(工序) Work_ID(工人) Date(记帐日期)
-----------------------------------------------------------
 001 1 1 2005-01-10
001 2 1 2005-01-12
001 2 3 2005-01-13
002 1 2 2005-01-08
002 2 1 2005-01-10
003 3 1 2005-10-04
003 1 2 2005-10-05
004 2 1 2005-08-20

 Table2(单据产品明细)
=========================================
PO_ID(单据编号) PRO_ID(产品编号) Total(产量)
-----------------------------------------
001 p1 100.00
001 p2 50.00
002 p3 1000.00
003 p2 800.00
004 p1 300.00
004 p3 100.00
004 p2 400.00

 Table3(产品资料表)
=====================================
PRO_ID(产品编号) PRO_NAME(名称)
 -------------------------------------
P1 红线
P2 白线
P3 黑线

 Table4(产品定额表)
==========================================================
PRO_ID(产品编号) WW_ID(工序) P_Mod(定额) Date(生效日期)
 ----------------------------------------------------------
P1 1 10.00 2005-01-01
P1 2 20.00 2005-06-01
P1 1 10.00 2005-06-01
P1 3 10.00 2005-06-01
P2 1 5.00 2005-02-05
P3 1 15.00 2005-01-05
P3 2 16.00 2005-01-05
P3 1 22.00 2005-08-05

注:1、产品的定额为:不同的工序不同的定额,并且定额可以自由增加修改。
  2、单据,单据工序明细和单据产品明细的对应关系是:多对多。如:单据编号为1的工序为1的工人1在2005-01-10生产了单据产品明细中所有产品,单据编

号为1的工序为2的工人1在2005-01-12也生产了单据产品明细中所有产品,……。

如现在想知道(单据)001中的产品P1的定额和工时,则先找到比(单据)001的记帐日期小或相等的生效日期。在Table2表中我们知道001号单中产品P1的定额应该

为P1在Table4的生效日期小于或等于001的记帐日期2005-01-10,工序有1和2,那么定额分别就是10.00和0.00了。如果没有产品的生效日期比记帐日期更小的,

那么就以0.00记!
工时等于产量除定额

现在问题就在这里了,我现在如果统计所有工序等于1的每一件产品共产品了多少工时,怎么做,我做的运行速度慢得我实在受不了了!望各位大哥给予帮助。



======================
我现在的做法,但我觉得太不可行了,因为太慢了!
select a1.工序编号,f1.笔数,a1.产品编号,d1.产品名称,E1.单位名称,
isnull(dbo.GetMP_HOUROF(a1.产品编号,b1.工序编号,b1.记帐日期),0) as 定额,
a1.产量,
case isnull(dbo.GetMP_HOUROF(a1.产品编号,b1.工序编号,b1.记帐日期),0) when
0 then 0
else a1.产量/dbo.GetMP_HOUROF(a1.产品编号,b1.工序编号,b1.记帐日期) end TotalHour,
b1.记帐日期
from Table2 a1
left outer join Table1 b1 on a1.单据编号=b1.单据编号
left outer join Table3 d1 on a1.产品编号=d1.产品编号
left outer join 单位 e1 on d1.单位编码=e1.单位编号
left outer join (select 单据编号,isnull(count(单据编号),0) as 笔数 from Table2 Group by 单据编号) f1 on a1.单据编号=f1.单据编号
where b1.工序编号=1



-----------------获取定额

CREATE FUNCTION GetMP_HOUROF (@产品编号 AS varchar(10),@工序编号 AS Int,@记帐日期 AS DateTime)
RETURNS numeric(9,2) AS
BEGIN
DECLARE @Max DATETIME
Select @Max=max(生效日期)
FROM Table4
WHERE Ltrim(str(YEAR(生效日期)))+Right(''0''+Ltrim(str(MONTH(生效日期))),2)+Right(''0''+Ltrim(str(DAY(生效日期))),2)
<=
Ltrim(str(YEAR(@记帐日期)))+Right(''0''+Ltrim(str(MONTH(@记帐日期))),2)+Right(''0''+Ltrim(str(DAY(@记帐日期))),2) AND
产品编号=@产品编号 and 工序编号=@工序编号
GROUP BY 产品编号,工序编号
RETURN (Select 定额
FROM Table4
WHERE 生效日期=@Max AND 产品编号=@产品编号 and 工序编号=@工序编号
)
END

2楼: 哈哈,帮yzxcsw推销一下,http://www.delphibbs.com/delphibbs/dispq.asp?lid=3222119 如金蝶财务软件的好处

3楼: 楼上的招挺好

4楼: 太长了,看都花,没法帮

5楼: -_-! 如果你不是做网页查询。。。我觉得没必要用表连接。。。

把你上面的那几个表连接和条件分出来,写成几个独立的查询效率应该比现在要高

还有。。。。看你上面那堆。。。-_-! 晕就一个字。。

6楼: 真的好大一坨呀,看着就头晕,呵呵


只大概看了下你的select语句
别用那left outer join
改用嵌套子查询,我保证你快

销售管理软件版7楼: 请sydan兄解惑:
我还有点不太理解这里:

按你要求,如统计单据001的工序2的产品工时时,p1产品记帐日期是那个呢?2005-01-10、2005-01-12还是2005-01-13

或者反过来,单据001在工序2上生产了哪些产品,产量是多少?

8楼: TO:yzxcsw兄
按你要求,如统计单据001的工序2的产品工时时,p1产品记帐日期是那个呢?2005-01-10、2005-01-12还是2005-01-13
=====================================
P1产品的记帐日期有3个,因为他是二个工序二个工人合作完成的。
  也就是说,在001号单中P1产品工序1时由员工1于2005-01-10生产,在工序2时由员工1于2005-01-12生产,在工序2时由员工3于2005-01-13生产。


或者反过来,单据001在工序2上生产了哪些产品,产量是多少?   
   =========================================================
工序号2员工1于2005-01-12天生产p1产品共100.00,和产品p2共50.00
工序号2员工3于2005-01-13天生产p1产品共100.00,和产品p2共50.00

这是一个多对多的表结构!按我现在的SQL可以得到正确结果,但太慢了,所以我拿出来请求各位一起思考,谢谢!

9楼: select a1.工序编号,f1.笔数,a1.产品编号,d1.产品名称,E1.单位名称,
isnull(dbo.GetMP_HOUROF(a1.产品编号,b1.工序编号,b1.记帐日期),0) as 定额,
a1.产量,
case isnull(dbo.GetMP_HOUROF(a1.产品编号,b1.工序编号,b1.记帐日期),0) when
0 then 0
else a1.产量/dbo.GetMP_HOUROF(a1.产品编号,b1.工序编号,b1.记帐日期) end TotalHour,
b1.记帐日期
from Table2 a1
left outer join Table1 b1 on a1.单据编号=b1.单据编号
left outer join Table3 d1 on a1.产品编号=d1.产品编号
left outer join 单位 e1 on d1.单位编码=e1.单位编号
left outer join (select 单据编号,isnull(count(单据编号),0) as 笔数 from Table2 Group by 单据编号) f1 on a1.单据编号=f1.单据编号
where b1.工序编号=1


条件 提前。

10楼: TO:hfghfghfg兄,我好像没有看到你做的与我提供的不同之入!

11楼: 试试这个:(查找工序为1的所有产品工时)
select a2.po_id,a2.pro_id,a1.ww_id,a1.work_id,a1.date,a4.a4date,a2.total,a4.p_mod,totalHour=
case
isnull(p_mod,0) when 0 then 0
else total/p_mod
end
from table2 a2
left join (select * from table1 where ww_id=1) a1 on a2.po_id=a1.po_id
left join (select pro_id,p_mod,date as a4date from table4 where ww_id=1) a4 on a2.pro_id=a4.pro_id
where date<=a4date or (a4date is null)

12楼: TO:yzxcsw兄!
  谢谢你一直的关注。
  刚才那句试不行,1、p_mod是当前工时单有多少笔产品,而非定额。
          2、date<=a4date时,同一产品有多个定额,而这样做的后果就是会产生很多多余的数据。而导至我最终的统计失败!
  烦请关注,谢谢…… 如服饰进销存管理软件

13楼: 把你的实际数据发一小点点过来,我再试试。
cheyz@126.com

1、p_mod是我按你给的table4表写的;你的定额字段是哪个?
2、按你的查询语句,同一个产品也会出现多个记帐日期呀?
3、根据你上面给的数据,我的方法试了可行呀?你还要怎么统计?

销售管理软件版14楼: 老大,太多了,我是没法看了。小生不才,可能也是没法搞定的。

15楼: 眼睛看的都疼了,还是没吧问题看明白,还能说的明白点啊,而且是不是能把表格重新设计下呢

16楼: TO:yzxcsw兄,
  对不起,p_mod我看错了,因为在我这里我将p_mod当成是当前工时单有多少笔产品,而非定额。
  这样的,同一个产品在不同的工序中是不同的定额,而且在同一个工序中又分不同的时段又有不同的定额。
  当然,同一个产品又分有多个记帐日期!

17楼: 看不懂呀

18楼: 这样的查询最好不用加连接操作,那样的话一定很慢的,你应该把那些连接查询改为用嵌套查询或是建立临时表或视图