我正在寻找SQL2016上的以下帮助
我有批次需要识别父批次。
我需要填写的是ParentBatchID,并且应该按照这个逻辑工作:
到目前为止,我用光标做了这个,但是你知道RBAR的性能。 *当当前fromDate介于之前和之后+ 1之后是isnull(parrentBatchID,batchid)*
我尝试使用窗口函数,但由于我需要继承的parrentID在下一行中不存在,我失败了,只是到处都是0-s :(
我对数据进行了自由操作,并尝试了各种准备方法。
Create table myTest (BatchID int, Product int, LenghtDay int, fromDate datetime, toDate Datetime, ParentBatchID int);
insert into myTest VALUES (1,1,9,'2000-01-01 00:00:00','2000-01-10 00:00:00',null);
insert into myTest VALUES (2,1,4,'2000-01-08 00:00:00','2000-01-12 00:00:00',null);
insert into myTest VALUES (3,1,5,'2000-01-13 00:00:00','2000-01-18 00:00:00',null);
insert into myTest VALUES (4,1,2,'2000-01-20 00:00:00','2000-01-22 00:00:00',null);
insert into myTest VALUES (5,2,7,'2000-01-21 00:00:00','2000-01-28 00:00:00',null);
预期输出
BatchID,ProductID,ParentBatchID
1,1,0
2,1,1 --as it's from (01.08) is between #1's from (01.01) and to+1 (01.11)
3,1,1 --as it's from (01.13) is between #2's from (01.08) and to+1 (01.13), so it needs to inherit #2's parent batch ID: 1
4,1,0 --as it's not between #3's from and to, it's a new batch
5,2,0 --as it's a different product, different batch
---------- 有一个扩展的问题版本,如果我识别parrent我需要延长它的长度与孩子的长度一天,我需要检查下一个孩子,如果它来自来自 - >到+之前的孩子们的长度。 坦率地说,我不知道如何实现这一点。 ---------- 扩展版本 - 第4行将是不同的
BatchID,ProductID,ParentBatchID
1,1,0
2,1,1 --as it's from (01.08) is between #1's from (01.01) and to+1 (01.11)
3,1,1 --as it's from (01.13) is between #1's from (01.01) and to+1+#2's length (01.10+1+4=016), so it needs to inherit #2's parent batch ID: 1
4,1,1 --! ParentBatchID=1 ! as it's from (01.20) is between the from (01.01) and to+1+extended by all previous children's length (01.10+1+4+5=01.20), so it needs to inherit #3's parent batch ID: 1
5,2,0 --as it's a different product, different batch
欢迎所有指导和帮助 提前谢谢
尼克洛
递归解决方案很棒,但只适用于最有限的数据集。你能建议一种更具伸缩性的方法吗?
谢谢
答案 0 :(得分:0)
import numpy as np
mas1 = np.array([[True, False, True],
[ False, True, True],
[ False, True, False]])
mas_answer = np.ndarray(shape=mas1.shape)
for i in range(mas1.shape[0]):
for j in range(mas1.shape[1]):
close_elt = []
if i >= 1:
try:
close_elt.append(mas1[i-1,j])
except:
pass
try:
close_elt.append(mas1[i-1,j+1])
except:
pass
if j >= 1:
try:
close_elt.append(mas1[i+1,j-1])
except:
pass
try:
close_elt.append(mas1[i,j-1])
except:
pass
if i >= 1 and j >= 1:
try:
close_elt.append(mas1[i-1,j-1])
except:
pass
try:
close_elt.append(mas1[i,j+1])
except:
pass
try:
close_elt.append(mas1[i+1,j])
except:
pass
try:
close_elt.append(mas1[i+1,j+1])
except:
pass
mas_answer[i,j] = close_elt.count(True)
# Ouput:
mas_answer
Out[27]:
array([[1., 4., 2.],
[3., 4., 3.],
[2., 2., 3.]])
http://sqlfiddle.com/#!18/971f3/37
;with t as
(
select tt.BatchID, tt.Product, tt.fromDate, tt.toDate, 0 ParentBatchID, 1 lvl, tt.BatchID rootID
from myTest tt
where not exists(select 1 from myTest t
where t.Product=tt.Product
and tt.BatchID <> t.BatchID
and tt.fromDate between t.fromDate and dateadd(day, 1, t.toDate)
)
union all
select tt.BatchID, tt.Product, tt.fromDate, tt.toDate, t.BatchID, t.lvl+1, t.rootID
from t
INNER JOIN myTest tt
on tt.Product = t.Product
where tt.BatchID <> t.BatchID
and tt.fromDate between t.fromDate and dateadd(day, 1, t.toDate)
)
select BatchId, Product, ParentBatchID, rootId, lvl
from t
order by Product, fromDate, lvl