我有一个难题。情况是我们有一个表(OSCL)。此表有一个子表(SCL4),它链接到更多表(ODLN - > DLN1)。
这里的技巧是,OSCL有一个递归链接回自身的条目(“u_callParent”字段中将包含一个与之对应的“CallID”。)
通常情况下,需要在查询中链接回0-3级别的“呼叫父母”。然而,一旦在蓝色的月亮中,父母召唤可能会有多达15级。
此查询的最终目标是数据集如下:
DLN1.DocEntry | ODLN.DocNum | DLN1.ItemCode | DLN1.StockPrice |
DLN1.Quantity | DLN1.LineNum | most parental call id | most child close date
以下是我正在处理的数据示例:
OSCL
--------------------------------------
CallID | u_callParent | CloseDate |
--------|-----------------------------
11638 | null | 7/1/2016 |
11688 | 11638 | 7/3/2016 |
12548 | 11688 | 7/7/2016 |
12705 | 12548 | 7/8/2016 |
12845 | 12705 | 7/15/2016 |
13321 | 12845 | 7/18/2016 |
13643 | 13321 | 7/21/2016 |
13661 | 13643 | 7/24/2016 |
13872 | 13661 | 7/29/2016 |
--------------------------------------
^
|
v
SCL4
------------------------
SrcvCallID | DocAbs |
------------|-----------
11638 | 7541 |
11688 | null |
12548 | null |
12705 | null |
12845 | 8993 |
13321 | 9305 |
13643 | 9335 |
13661 | 9408 |
13872 | 10519 |
------------------------
^
/
/
/
/
/
v
ODLN
------------------------
DocEntry | DocNum |
------------|-----------
7541 | 9540 |
8993 | 10992 |
9305 | 11304 |
9335 | 11334 |
9408 | 11407 |
10519 | 12518 |
------------------------
^
|
v
DLN1
----------------------------------------------------
DocEntry | ItemCode | Quantity | LineNum |
------------|---------------------------------------
7541 | 6LH06990000 | 1 | 0 |
7541 | 6LE49877000 | 1 | 1 |
8993 | 6LE09191000 | 1 | 0 |
8993 | 6LE09788000 | 1 | 1 |
8993 | 6LE09132000 | 1 | 2 |
8993 | 6LE09155000 | 1 | 3 |
8993 | C010814000 | 1 | 4 |
8993 | 6LH72649000 | 1 | 5 |
9305 | LaborDefault | 2.113 | 0 |
9335 | LaborDefault | 1 | 0 |
9408 | LaborDefault | 1.131 | 0 |
10519 | LaborDefault | 3.213 | 0 |
10519 | 6LA15184000 | 3 | 1 |
10519 | 6LE09604000 | 1 | 2 |
----------------------------------------------------
Goal Results
------------
DocEntry | DocNum | ItemCode | Quantity | LineNum | CallID | CloseDate |
-------------------------------------------------------------------------
7541 | 9540 | 6LH... | 1 | 0 | 11638 | 7/29/2016 |
7541 | 9540 | 6LE4... | 1 | 1 | 11638 | 7/29/2016 |
8993 | 10992 | 6LE0... | 1 | 0 | 11638 | 7/29/2016 |
8993 | 10992 | etc... | 1 | 1 | 11638 | 7/29/2016 |
8993 | 10992 | | 1 | 2 | 11638 | 7/29/2016 |
8993 | 10992 | | 1 | 3 | 11638 | 7/29/2016 |
8993 | 10992 | | 1 | 4 | 11638 | 7/29/2016 |
8993 | 10992 | | 1 | 5 | 11638 | 7/29/2016 |
9305 | 11304 | | 2.113 | 0 | 11638 | 7/29/2016 |
9335 | 11334 | | 1 | 0 | 11638 | 7/29/2016 |
9408 | 11407 | | 1.131 | 0 | 11638 | 7/29/2016 |
10519 | 12518 | | 3.213 | 0 | 11638 | 7/29/2016 |
10519 | 12518 | | 3 | 1 | 11638 | 7/29/2016 |
10519 | 12518 | | 1 | 2 | 11638 | 7/29/2016 |
-------------------------------------------------------------------------
箭头表示表格之间的链接。
我编写了以下查询,返回了正确的结果;然而,仅运行1:57只能运行23行(限制器来自始发呼叫11638)。问题是我需要在where语句中使用日期范围参数运行它,并且我们不希望每次重新运行此查询时等待2分钟以上。
select s1.*
, max(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(child15.callid, child14.callid),child13.callid),child12.callid),child11.callid),child10.callid),child9.callid),child8.callid),child7.callid),child6.callid),child5.callid),child4.callid),child3.callid),child2.callid),child1.callid),oscl.callID)) MinCallID
FROM (
select odln.docentry
, odln.docnum
, dln1.itemcode
, dln1.Quantity
, dln1.LineNum
, min(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(isnull(parent15.callid, parent14.callid),parent13.callid),parent12.callid),parent11.callid),parent10.callid),parent9.callid),parent8.callid),parent7.callid),parent6.callid),parent5.callid),parent4.callid),parent3.callid),parent2.callid),parent1.callid),oscl.callID)) MinCallID
from SCL4
inner join odln on odln.DocEntry = scl4.DocAbs
left join dln1 on dln1.DocEntry = odln.DocEntry
left join oscl on oscl.callid = scl4.SrcvCallID
left join oscl parent1 on oscl.U_callParent = parent1.callID
left join oscl parent2 on parent1.U_callParent = parent2.callID
left join oscl parent3 on parent2.U_callParent = parent3.callID
left join oscl parent4 on parent3.U_callParent = parent4.callID
left join oscl parent5 on parent4.U_callParent = parent5.callID
left join oscl parent6 on parent5.U_callParent = parent6.callID
left join oscl parent7 on parent6.U_callParent = parent7.callID
left join oscl parent8 on parent7.U_callParent = parent8.callID
left join oscl parent9 on parent8.U_callParent = parent9.callID
left join oscl parent10 on parent9.U_callParent = parent10.callID
left join oscl parent11 on parent10.U_callParent = parent11.callID
left join oscl parent12 on parent11.U_callParent = parent12.callID
left join oscl parent13 on parent12.U_callParent = parent13.callid
left join oscl parent14 on parent13.U_callParent = parent14.callID
left join oscl parent15 on parent14.U_callParent = parent15.callID
group by odln.docentry
, odln.docnum
, dln1.itemcode
, dln1.Quantity
, dln1.LineNum
) s1
left join oscl on oscl.callid = s1.MinCallID
left join oscl child1 on child1.U_callParent = oscl.callID
left join oscl child2 on child2.U_callParent = child1.callID
left join oscl child3 on child3.U_callParent = child2.callID
left join oscl child4 on child4.U_callParent = child3.callID
left join oscl child5 on child5.U_callParent = child4.callID
left join oscl child6 on child6.U_callParent = child5.callID
left join oscl child7 on child7.U_callParent = child6.callID
left join oscl child8 on child8.U_callParent = child7.callID
left join oscl child9 on child9.U_callParent = child8.callID
left join oscl child10 on child10.U_callParent = child9.callID
left join oscl child11 on child11.U_callParent = child10.callID
left join oscl child12 on child12.U_callParent = child11.callID
left join oscl child13 on child13.U_callParent = child12.callid
left join oscl child14 on child14.U_callParent = child13.callID
left join oscl child15 on child15.U_callParent = child14.callID
--where MinCallID = 11638
group by s1.docentry
, s1.docnum
, s1.itemcode
, s1.stockprice
, s1.Quantity
, s1.LineNum
, s1.MinCallID
order by s1.mincallid, docentry, LineNum
我知道这有点吝啬,而且必须有更好的方法来写它,但对于我的生活,我无法理解。
我也无法对数据库表添加任何修改(因此我无法添加称为“始发呼叫”或其他任何内容的字段)。
对于它的价值,这些表都基于SAP Business One,在OSCL上使用UDF for u_callParent。
编辑:
根据以下评论,我已将查询更新为:
with cte as (
SELECT
OSCL.CallID
, OSCL.U_callParent
, PLevel = 0
, TopParent = CallID
FROM OSCL
WHERE U_callParent is null
UNION ALL
SELECT
OSCL.CallID
, OSCL.U_callParent
, PLevel = cte.Plevel + 1
, cte.TopParent
FROM OSCL
INNER JOIN cte on oscl.U_callParent = cte.callID
)
SELECT
cte.* , scl4.DocAbs, scl4.Object
FROM cte
left join scl4 on scl4.SrcvCallID = cte.callID
where TopParent = 11638
现在的问题是我需要获取OSCL.CloseDate以获取“最幼稚”的信息,而且我不确定这样做的好方法。有什么想法吗?
编辑2:
好吧,看起来我想通了:
with cte as (
SELECT
OSCL.CallID
, OSCL.U_callParent
, PLevel = 0
, TopParent = CallID
FROM OSCL
WHERE U_callParent is null
UNION ALL
SELECT
OSCL.CallID
, OSCL.U_callParent
, PLevel = cte.Plevel + 1
, cte.TopParent
FROM OSCL
INNER JOIN cte on oscl.U_callParent = cte.callID
)
SELECT
odln.docentry, odln.docnum, dln1.itemcode, dln1.quantity, dln1.linenum, cte.TopParent, child.closeDate
FROM cte
left join scl4 on scl4.SrcvCallID = cte.callID
left join (SELECT max(callid) callID, topParent from cte group by topParent) s1 on s1.TopParent = cte.TopParent
inner join oscl Child on Child.callID = s1.callID
left join odln on odln.ObjType = scl4.Object and odln.DocEntry = scl4.DocAbs
left join dln1 on dln1.DocEntry = odln.DocEntry
where cte.TopParent = 11638
如果在我上一个select语句中使用子查询的方法比在上一个select语句中使用更好,请告诉我,但这似乎很快就会运行。
答案 0 :(得分:1)
with cte as (
SELECT
OSCL.CallID
, OSCL.U_callParent
, PLevel = 0
, TopParent = CallID
FROM OSCL
WHERE U_callParent is null
UNION ALL
SELECT
OSCL.CallID
, OSCL.U_callParent
, PLevel = cte.Plevel + 1
, cte.TopParent
FROM OSCL
INNER JOIN cte on oscl.U_callParent = cte.callID
)
SELECT
odln.docentry, odln.docnum, dln1.itemcode, dln1.quantity, dln1.linenum, cte.TopParent, child.closeDate
FROM cte
left join scl4 on scl4.SrcvCallID = cte.callID
left join (SELECT max(callid) callID, topParent from cte group by topParent) s1 on s1.TopParent = cte.TopParent
inner join oscl Child on Child.callID = s1.callID
left join odln on odln.ObjType = scl4.Object and odln.DocEntry = scl4.DocAbs
left join dln1 on dln1.DocEntry = odln.DocEntry
where cte.TopParent = 11638
这是我发现最终工作的解决方案。