0

为了验证交付是否按时完成,我需要根据所需数量 (ReqQty) 和交付数量 (DlvQty) 之间的比较,将交付文档与采购订单计划行 (SchLin) 匹配。

Delivery Docs 有对 PO 和 POItm 的引用,但没有对 SchLin 的引用。将交付单据分配到计划行后,我可以将交付增量 (DlvDelta) 计算为与需求 (ReqDate) 相比提前或延迟交付的天数。

两个基表的示例如下:

计划行

PO  POItm   SchLin  ReqDate ReqQty
123 1       1       10/11   20
123 1       2       30/11   30
124 2       1       15/12   10
124 2       2       24/12   15

交货单

Doc Item    PO  POItm   DlvDate DlvQty
810 1       123 1       29/10   12
816 1       123 1       02/11   07
823 1       123 1       04/11   13
828 1       123 1       06/11   08
856 1       123 1       10/11   05
873 1       123 1       14/11   09
902 1       124 2       27/11   05
908 1       124 2       30/11   07
911 1       124 2       08/12   08
923 1       124 2       27/12   09

重要提示:计划行和交货应具有相同的 PO 和 POItm。链接的另一个逻辑是对 DlvQty 求和,直到我们达到(或超过)ReqQty。然后将这些交付链接到计划行。后续交货用于以下计划行。一个交付应该只匹配一个计划行。

比较 ReqQty 和 DlvQty 后,分配应导致以下结果:

结果

Doc Item    PO  POItm   Schlin  ReqDate DlvDate DlvDelta
810 1       123 1       1       10/11   29/10   -11
816 1       123 1       1       10/11   02/11   -08
823 1       123 1       1       10/11   04/11   -06
828 1       123 1       2       30/11   06/11   -24
856 1       123 1       2       30/11   10/11   -20
873 1       123 1       2       30/11   14/11   -16
902 1       124 2       1       15/12   27/11   -18
908 1       124 2       1       15/12   30/11   -15
911 1       124 2       2       24/12   08/12   -16
923 1       124 2       2       24/12   27/12   +03

到目前为止,我已经通过使用游标的循环来完成此操作,但性能相当缓慢。

SQL(脚本)中是否有另一种方法,例如通过比较措施来实现相同结果的连接?

问候,

埃里克

4

1 回答 1

0

如果您可以表达将交货与计划行匹配的规则,则可以在单个查询中生成所需的结果。而且,是的,我保证它会比在游标上的循环中执行相同的逻辑更快(更简单)。

我无法重现您的确切结果,因为我不太了解这两个表的关系。希望通过下面的代码,您将能够通过调整连接条件来解决这个问题。

我没有你的 DBMS。我的代码使用 SQLite,它有自己独特的日期函数。您必须替换系统提供的那些。无论如何,我不能推荐 5 个字符的日期字符串。如果您有日期时间类型,请使用日期时间类型,并且无论如何都包括 4 位数年份。否则圣诞节和元旦之间有多少天?

create table S (
    PO int not NULL,
    POItm int not NULL,
    SchLin int not NULL,
    ReqDate char not NULL, 
    ReqQty int not NULL,
    primary key (PO, POItm, SchLin)
    );

insert into S values
(123, 1,       1,       '10/11',   20 ), 
(123, 1,       2,       '30/11',   30 ), 
(124, 2,       1,       '15/12',   10 ), 
(124, 2,       2,       '24/12',   15 );

create table D (
       Doc int not NULL, 
       Item int not NULL, 
       PO int not NULL, 
       POItm int not NULL, 
       DlvDate char not NULL, 
       DlvQty int not NULL,
       primary key (Doc, Item)
); 

insert into D values 
(810, 1,       123, 1,       '29/10',   12 ), 
(816, 1,       123, 1,       '02/11',   07 ), 
(823, 1,       123, 1,       '04/11',   13 ), 
(828, 1,       123, 1,       '06/11',   08 ), 
(856, 1,       123, 1,       '10/11',   05 ), 
(873, 1,       123, 1,       '14/11',   09 ), 
(902, 1,       124, 2,       '27/11',   05 ), 
(908, 1,       124, 2,       '30/11',   07 ), 
(911, 1,       124, 2,       '08/12',   08 ), 
(923, 1,       124, 2,       '27/12',   09 );

select D.Doc, D.Item, D.PO, S.SchLin, S.ReqDate, D.DlvDate
, cast(
    julianday('2018-' || substr(DlvDate, 4,2) || '-' || substr(DlvDate, 1,2))
  - julianday('2018-' || substr(ReqDate, 4,2) || '-' || substr(ReqDate, 1,2))
  as int) as DlvDelta
from S join D on S.PO = D.PO and S.POItm = D.POItm
;

结果:

Doc         Item        PO          SchLin      ReqDate     DlvDate     DlvDelta  
----------  ----------  ----------  ----------  ----------  ----------  ----------
810         1           123         1           10/11       29/10       -12       
810         1           123         2           30/11       29/10       -32       
816         1           123         1           10/11       02/11       -8        
816         1           123         2           30/11       02/11       -28       
823         1           123         1           10/11       04/11       -6        
823         1           123         2           30/11       04/11       -26       
828         1           123         1           10/11       06/11       -4        
828         1           123         2           30/11       06/11       -24       
856         1           123         1           10/11       10/11       0         
856         1           123         2           30/11       10/11       -20       
873         1           123         1           10/11       14/11       4         
873         1           123         2           30/11       14/11       -16       
902         1           124         1           15/12       27/11       -18       
902         1           124         2           24/12       27/11       -27       
908         1           124         1           15/12       30/11       -15       
908         1           124         2           24/12       30/11       -24       
911         1           124         1           15/12       08/12       -7        
911         1           124         2           24/12       08/12       -16       
923         1           124         1           15/12       27/12       12        
923         1           124         2           24/12       27/12       3         
于 2018-11-21T21:10:01.867 回答