Scrap Cost CTE

,

I have a BAQ that attempts to estimate the cost that went into scrapped parts. It should recursively search the parent and children assemblies, and materials for subassemblies that have been worked on prior to the scrap being generated. Despite the best efforts of folks here, I still don’t understand CTEs. I am pretty sure it is necessary for this kind of recursive search.

So for better or worse, I have been using GPT to write SQL. It does a terrible job, and can’t follow Epicor’s rules about aliases. But it seems to know how to structure a CTE better than I do. Once I correct the errors, I got this BAQ:

LastWeekScrapCost.baq (18.6 KB)

LastWeekScrapCost - Looks back at the labor from last week, and only considers parts that were scrapped. For these parts, it should pull the assembly, and operations, along with costs from JobOper. It will roll those up and give a unit cost, and a total scrap cost (unit cost * scrapped parts). It keeps the labor, materials, burden, and subcontract costs separated while we verify this makes sense.

I have an example job I am trying to make sure I get all the costs from. In this case, Asm 0, Op 70 has a material needed. That material is Asm 1. So if a part is scrapped at op 70, then the work done on Asm 1 needs to be included in the costs. If the part is scrapped before op 70, then that extra assembly hasn’t been worked on yet, or at least it hasn’t been consumed by the job, so no cost is associated.

This is the part I can’t get to work. The BAQ pulls in subassemblies, but not if the subassembly is a material on an operation.

Clearly I still don’t understand CTEs. I have not been able to build one by myself, but I can edit the ones already made. Can you tell what I am missing here? I feel like it is a small step to the finish line.

Thank you for your time!

1 Like

FFT_machinehourbyresourcepart.baq (196.3 KB)
I can’t open your BAQ, since we’re still on 2024.2.

I have attached a CTE I made to marry up average production costs for made to stock parts with sales data, parts of it may be useful.

I would need some more details or ability to see the BAQ to help troubleshoot directly. You have some shortcuts you can use with lower level and upper level costs if costs are your goal. This is more complicated if you made to stock sub assmeblies that show up as materials in your BOM structure.

Here is another CTE that wraps up the BOM to compare costs sets for raw materials- parts may be helpful.
FFT_PartCostComponents.baq (228.3 KB)

2 Likes

I couldn’t make sense of the BAQs you posted. Here is the SQL for mine:

with [AssemblyHierarchy] as 
(select  
	[ja].[Company] as [Company], 
	[ja].[JobNum] as [JobNum], 
	[ja].[AssemblySeq] as [AssemblySeq], 
	[ja].[Parent] as [Parent], 
	[JobHead].[PartNum] as [JobHead_PartNum], 
	[ja].[PartNum] as [ja_PartNum], 
	(0) as [Calculated_LevelDepth], 
	(ja.AssemblySeq) as [Calculated_RootAssembly] 

from Erp.JobAsmbl as [ja]
inner join Erp.LaborDtl as [ld] on 
	  ja.Company = ld.Company
	and  ja.JobNum = ld.JobNum
	and  ja.AssemblySeq = ld.AssemblySeq
inner join Erp.JobHead as [JobHead] on 
	  ja.Company = JobHead.Company
	and  ja.JobNum = JobHead.JobNum
where ( ld.ScrapQty > 0  
and ld.PayrollDate >= @FirstDayOfPrevWeek  
and ld.PayrollDate <= @LastDayOfPrevWeek  )
union all
select  
	[child].[Company] as [child_Company], 
	[child].[JobNum] as [child_JobNum], 
	[child].[AssemblySeq] as [child_AssemblySeq], 
	[child].[Parent] as [child_Parent], 
	[parent].[JobHead_PartNum] as [JobHead_PartNum], 
	[parent].[ja_PartNum] as [ja_PartNum], 
	((parent.Calculated_LevelDepth + 1)) as [Calculated_LevelDepth], 
	[parent].[Calculated_RootAssembly] as [Calculated_RootAssembly] 

from Erp.JobAsmbl as [child]
inner join  AssemblyHierarchy  as [parent] on 
	  child.Company = parent.Company
	and  child.JobNum = parent.JobNum
	and  child.Parent = parent.AssemblySeq
	and  child.AssemblySeq <> parent.AssemblySeq)
 ,[Scrap] as 
(select  
	[ld1].[Company] as [ld1_Company], 
	[ld1].[JobNum] as [ld1_JobNum], 
	[ld1].[AssemblySeq] as [ld1_AssemblySeq], 
	[ld1].[OprSeq] as [ld1_OprSeq], 
	(sum(ld1.ScrapQty)) as [Calculated_ScrapQty] 

from Erp.LaborDtl as [ld1]
where ( ld1.ScrapQty > 0  
and ld1.PayrollDate >= @FirstDayOfPrevWeek  
and ld1.PayrollDate <= @LastDayOfPrevWeek  )
group by 
	[ld1].[Company], 
	[ld1].[JobNum], 
	[ld1].[AssemblySeq], 
	[ld1].[OprSeq])
 ,[AccumulatedCost] as 
(select  
	[s].[ld1_Company] as [ld1_Company], 
	[s].[ld1_JobNum] as [ld1_JobNum], 
	[h].[JobHead_PartNum] as [JobHead_PartNum], 
	[s].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[h].[ja_PartNum] as [ja_PartNum], 
	[s].[ld1_OprSeq] as [ld1_OprSeq], 
	[s].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	(((isnull(jo.ActLabCost, 0) + isnull(jo.ActBurCost, 0)) + isnull(jm.TotalCost, 0))) as [Calculated_TotalAccumulatedCost], 
	(isnull(jo.QtyCompleted, 0)) as [Calculated_QtyCompleted], 
	[jo].[OprSeq] as [jo_OprSeq], 
	[jo].[SubContract] as [jo_SubContract], 
	[jo].[ActBurCost] as [jo_ActBurCost], 
	[jo].[ActLabCost] as [jo_ActLabCost], 
	[jm].[TotalCost] as [jm_TotalCost] 

from  Scrap  as [s]
inner join  AssemblyHierarchy  as [h] on 
	  s.ld1_Company = h.Company
	and  s.ld1_JobNum = h.JobNum
	and  s.ld1_AssemblySeq = h.AssemblySeq
left outer join Erp.JobOper as [jo] on 
	  h.Company = jo.Company
	and  h.JobNum = jo.JobNum
	and  h.AssemblySeq = jo.AssemblySeq
	and ( jo.OprSeq <= s.ld1_OprSeq  )
left outer join Erp.JobMtl as [jm] on 
	  jo.Company = jm.Company
	and  jo.JobNum = jm.JobNum
	and  jo.AssemblySeq = jm.AssemblySeq
	and  jo.OprSeq = jm.RelatedOperation)

select distinct 
	[AccumulatedCost].[ld1_Company] as [ld1_Company], 
	[AccumulatedCost].[ld1_JobNum] as [ld1_JobNum], 
	[AccumulatedCost].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[AccumulatedCost].[ld1_OprSeq] as [ld1_OprSeq], 
	[AccumulatedCost].[JobHead_PartNum] as [JobHead_PartNum], 
	[AccumulatedCost].[ja_PartNum] as [ja_PartNum], 
	[AccumulatedCost].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[AccumulatedCost].[jo_OprSeq] as [jo_OprSeq], 
	(iif(AccumulatedCost.Calculated_QtyCompleted=0,0,iif(AccumulatedCost.Calculated_TotalAccumulatedCost=0,0,AccumulatedCost.Calculated_TotalAccumulatedCost / AccumulatedCost.Calculated_QtyCompleted))) as [Calculated_UnitCostAtScrap], 
	(iif(AccumulatedCost.Calculated_QtyCompleted=0,0,iif(AccumulatedCost.Calculated_TotalAccumulatedCost=0,0,iif(AccumulatedCost.Calculated_ScrapQty=0,0,(((AccumulatedCost.Calculated_TotalAccumulatedCost / AccumulatedCost.Calculated_QtyCompleted)) * AccumulatedCost.Calculated_ScrapQty) )))) as [Calculated_ScrapCost], 
	(iif(iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted)=0,0,iif(AccumulatedCost.jo_SubContract=0, AccumulatedCost.jo_ActLabCost/ iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted), 0))) as [Calculated_LabTot], 
	(iif(iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted)=0,0,AccumulatedCost.jm_TotalCost / iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted))) as [Calculated_MatTot], 
	(iif(iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted)=0,0,iif(AccumulatedCost.jo_SubContract=1, AccumulatedCost.jo_ActLabCost/ iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted), 0))) as [Calculated_SCTot], 
	(iif(iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted)=0,0,AccumulatedCost.jo_ActBurCost / iif(AccumulatedCost.Calculated_QtyCompleted=0,0,AccumulatedCost.Calculated_QtyCompleted))) as [Calculated_BurTot] 

from  AccumulatedCost  as [AccumulatedCost]

You may be able to import this as SQL into the new BAQ editor. Make sure you add the parameters JobNum, AssemblySeq, and ThruOp. If you paste in the SQL, you may have to fix all the issues Kinetic creates, like using expressions instead of parameters.

The thinking is that we run this once a week to understand the costs that went into parts that were scrapped.

Conceptually this BAQ starts at AssemblyHierarchy CTE. This CTE pulls JobHead, JobAsmbl, and LaborDtl. It only looks at labor entries for last week, that had scrap. From that we pull the top part number, and assembly part number.

The next step is the AssemblyHierarchy UnionAll. Using JobAsmbl, and the previously created CTE. I think this is part of the recursive nature of the CTE. I don’t fully understand it.

The next step is the Scrap CTE, which looks at LaborDtl, and pull scrap quantity. by job/asm/op. Scrap CTE and AssemblyHierarchy CTE both use the same set of subquery criteria to get scrap labor entries from last week.

Next is the AccumulatedCostCTE. This is where all the costs get identified and gathered up. We start with the scrap table, join in the hierarchy, and then join in the job op and mtl tables to get those costs.

Finally, at the top level we pull all the data together, and calculate some totals.

I may be stuck thinking through the frame of how our methods are setup.. :slight_smile:

I don’t think the sql to baq tool is converting this correctly :slight_smile:

Your end goal is to summarize all the scrap from JO during a time frame and the costs associated with it. The costs can be accrued through both subassemblies ( time and materials) and materials and time on the assembly related to the scrap. Some of the materials on that assembly could have assemblies of their own. Do you wish to pull those in to the cost at a standard or pull in those BOM/MOM costs as well?

I think you need a CTE for capturing the materials that have methods… if you want, not the assembly costs.

The TLA/LLA cost elements here can capture that for you? Whatever assembly level the scrap is on, add the TLA and LLA elements. Or use the LLA costs for lower assemblies and get more precise with the scrap related assembly in another subquery.

General thoughts: I’ve always used CTE and unions together. Using a common term in tables to unite datasets. This is what you are aiming at in your two assemblyheiarchy (CTE/uinion) subqueries. I don’t think you need to do this to pulls costs at an assembly level. Just link the labor records filtered down to what you want to the assembly.

1 Like

Also, are you not pulling scrap costs from jobs to DMR when a NCM is processed? This will pull the exact cost(for NCM qty) at that point from the job and put it on the DMR.

If your management/accounting teams like the idea…
When a scrap qty is claimed on an operation and goes to inspection processing, you can check this box. This will move the cost to the DMR and you could report costs from the DMR directly.

1 Like

I’m not sure what those are! We don’t have the quality module. I have not seen those TLA and LLA fields before, what table are those in?

1 Like

They are in the jobassm table

1 Like

I think the same data exists in JobOper actual costs and in JobAsmbl this level / lower level costs. I can’t really tell how the TLA/LLA are built, so I don’t know how much to trust them. Is TLA/LLA preferred over JobOper.ActLabCost, ActBurCost?

This depends on what you are trying to do. The TLA/LLA costs are for the full assembly for each cost element.

I moved away from using TLA/LLA costs. They didn’t have the level of detail that I needed. It seems that JobOper.ActLab and ActBur contain the correct costs I need to sum.

However, I can’t get this CTE to roll everythign up properly. Granted, AI helped me start it, but I have heavily modified it. Now for some jobs it shows the correct data. But if the job contains a subassmebly as a material resource for an operation, then those costs are blowing up the whole CTE.

I think the first part is correct, where the costs are rolled up in AccumulatedCost. At least until the calculated “Mtl” fields I added. If the job has assemblies as materials on an op, then I have to add up the costs on this side.

I think I need a two-step CTE. The first would roll up the costs for operations less than or equal to the operation where the scrap was generated. The second, would review those operations, and if any of them contain another assembly, then add up the costs the same way for those assemblies.

I am terrible at CTEs and don’t really understand how it works. I have had some of the brightest folks here try to teach me. But I still don’t get it. I get the concept, but the structure and syntax are so unintuitive.

I’d really appreciate any help from you CTE experts out there. I think I need to break off the second half of the query in AccumulatedCosts, and make a CTE out of that. Then later combine it with the other accumulated costs.

Here is the SQL and BAQ:

/*  
 * Disclaimer!!! 
 * This is not a real query being executed, but a simplified version for general vision. 
 * Executing it with any other tool may produce a different result. 
 */
with [AssemblyHierarchy] as 
(select  
	[ja].[Company] as [Company], 
	[ja].[JobNum] as [JobNum], 
	[ja].[AssemblySeq] as [AssemblySeq], 
	[ja].[Parent] as [Parent], 
	[JobHead].[PartNum] as [JobHead_PartNum], 
	[ja].[PartNum] as [ja_PartNum], 
	(0) as [Calculated_LevelDepth], 
	(ja.AssemblySeq) as [Calculated_RootAssembly] 

from Erp.JobAsmbl as [ja]
inner join Erp.LaborDtl as [ld] on 
	  ja.Company = ld.Company
	and  ja.JobNum = ld.JobNum
	and  ja.AssemblySeq = ld.AssemblySeq
inner join Erp.JobHead as [JobHead] on 
	  ja.Company = JobHead.Company
	and  ja.JobNum = JobHead.JobNum
where ( ld.ScrapQty > 0  
and ld.PayrollDate >= @FirstDayOfPrevWeek  
and ld.PayrollDate <= @LastDayOfPrevWeek  ))
 ,[Scrap] as 
(select  
	[ld1].[Company] as [ld1_Company], 
	[ld1].[JobNum] as [ld1_JobNum], 
	[ld1].[AssemblySeq] as [ld1_AssemblySeq], 
	[ld1].[OprSeq] as [ld1_OprSeq], 
	(sum(ld1.ScrapQty)) as [Calculated_ScrapQty] 

from Erp.LaborDtl as [ld1]
where ( ld1.ScrapQty > 0  
and ld1.PayrollDate >= @FirstDayOfPrevWeek  
and ld1.PayrollDate <= @LastDayOfPrevWeek  )
group by 
	[ld1].[Company], 
	[ld1].[JobNum], 
	[ld1].[AssemblySeq], 
	[ld1].[OprSeq])
 ,[AccumulatedCost] as 
(select  
	[s].[ld1_Company] as [ld1_Company], 
	[s].[ld1_JobNum] as [ld1_JobNum], 
	[h].[JobHead_PartNum] as [JobHead_PartNum], 
	[s].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[h].[ja_PartNum] as [ja_PartNum], 
	[s].[ld1_OprSeq] as [ld1_OprSeq], 
	[s].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	(isnull(jo.QtyCompleted, 0)) as [Calculated_QtyCompleted], 
	[jo].[OprSeq] as [jo_OprSeq], 
	[jo].[SubContract] as [jo_SubContract], 
	(jo.ActLabCost) as [Calculated_OpActLab], 
	(jo.ActBurCost) as [Calculated_OpActBur], 
	[jm].[TotalCost] as [jm_TotalCost], 
	[JobOper].[AssemblySeq] as [JobOper_AssemblySeq], 
	[JobOper].[OprSeq] as [JobOper_OprSeq], 
	[JobOper].[ActBurCost] as [JobOper_ActBurCost], 
	[JobOper].[ActLabCost] as [JobOper_ActLabCost], 
	[JobOper].[SubContract] as [JobOper_SubContract], 
	[JobMtl].[TotalCost] as [JobMtl_TotalCost], 
	(isnull(JobOper.QtyCompleted, 0)) as [Calculated_MtlQtyCompl], 
	[JobAsmbl].[RelatedOperation] as [JobAsmbl_RelatedOperation] 

from  Scrap  as [s]
inner join  AssemblyHierarchy  as [h] on 
	  s.ld1_Company = h.Company
	and  s.ld1_JobNum = h.JobNum
	and  s.ld1_AssemblySeq = h.AssemblySeq
left outer join Erp.JobOper as [jo] on 
	  h.Company = jo.Company
	and  h.JobNum = jo.JobNum
	and  h.AssemblySeq = jo.AssemblySeq
	and ( jo.OprSeq <= s.ld1_OprSeq  )
left outer join Erp.JobMtl as [jm] on 
	  jo.Company = jm.Company
	and  jo.JobNum = jm.JobNum
	and  jo.AssemblySeq = jm.AssemblySeq
	and  jo.OprSeq = jm.RelatedOperation
left outer join Erp.JobAsmbl as [JobAsmbl] on 
	  jo.Company = JobAsmbl.Company
	and  jo.JobNum = JobAsmbl.JobNum
	and  jo.OprSeq = JobAsmbl.RelatedOperation
left outer join Erp.JobOper as [JobOper] on 
	  JobAsmbl.Company = JobOper.Company
	and  JobAsmbl.JobNum = JobOper.JobNum
	and  JobAsmbl.AssemblySeq = JobOper.AssemblySeq
left outer join Erp.JobMtl as [JobMtl] on 
	  JobOper.Company = JobMtl.Company
	and  JobOper.JobNum = JobMtl.JobNum
	and  JobOper.AssemblySeq = JobMtl.AssemblySeq
	and  JobOper.OprSeq = JobMtl.RelatedOperation)

select  
	[MtlTotal].[ld1_JobNum] as [ld1_JobNum], 
	[MtlTotal].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[MtlTotal].[ld1_OprSeq] as [ld1_OprSeq], 
	[MtlTotal].[JobHead_PartNum] as [JobHead_PartNum], 
	[MtlTotal].[ja_PartNum] as [ja_PartNum], 
	[MtlTotal].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[MtlTotal].[jo_OprSeq] as [jo_OprSeq], 
	[MtlTotal].[Calculated_LabTot] as [Calculated_LabTot], 
	[MtlTotal].[Calculated_AllMatTot] as [Calculated_AllMatTot], 
	[MtlTotal].[Calculated_SCTot] as [Calculated_SCTot], 
	[MtlTotal].[Calculated_BurTot] as [Calculated_BurTot], 
	[MtlTotal].[jo_SubContract] as [jo_SubContract], 
	(isnull(MtlTotal.Calculated_LabTot,0) +
isnull(MtlTotal.Calculated_AllMatTot,0)+
isnull(MtlTotal.Calculated_SCTot,0)+
isnull(MtlTotal.Calculated_BurTot,0)) as [Calculated_TotalCost], 
	[MtlTotal].[Calculated_MtlMatTot] as [Calculated_MtlMatTot], 
	[MtlTotal].[Calculated_MLabTot] as [Calculated_MLabTot], 
	[MtlTotal].[Calculated_MMatTot] as [Calculated_MMatTot], 
	[MtlTotal].[Calculated_MSCTot] as [Calculated_MSCTot], 
	[MtlTotal].[Calculated_MBurTot] as [Calculated_MBurTot], 
	[MtlTotal].[JobOper_AssemblySeq] as [JobOper_AssemblySeq], 
	[MtlTotal].[JobOper_OprSeq] as [JobOper_OprSeq] 

from  (select  
	[Main].[ld1_JobNum] as [ld1_JobNum], 
	[Main].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[Main].[ld1_OprSeq] as [ld1_OprSeq], 
	[Main].[JobHead_PartNum] as [JobHead_PartNum], 
	[Main].[ja_PartNum] as [ja_PartNum], 
	[Main].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[Main].[jo_OprSeq] as [jo_OprSeq], 
	[Main].[Calculated_LabTot] as [Calculated_LabTot], 
	(sum(Main.Calculated_MatTot)) as [Calculated_AllMatTot], 
	[Main].[Calculated_SCTot] as [Calculated_SCTot], 
	[Main].[Calculated_BurTot] as [Calculated_BurTot], 
	[Main].[jo_SubContract] as [jo_SubContract], 
	[Main].[JobOper_AssemblySeq] as [JobOper_AssemblySeq], 
	[Main].[JobOper_OprSeq] as [JobOper_OprSeq], 
	[Main].[Calculated_MtlMatTot] as [Calculated_MtlMatTot], 
	[Main].[Calculated_MLabTot] as [Calculated_MLabTot], 
	[Main].[Calculated_MMatTot] as [Calculated_MMatTot], 
	[Main].[Calculated_MSCTot] as [Calculated_MSCTot], 
	[Main].[Calculated_MBurTot] as [Calculated_MBurTot] 

from  (select distinct 
	[AccumulatedCost].[ld1_Company] as [ld1_Company], 
	[AccumulatedCost].[ld1_JobNum] as [ld1_JobNum], 
	[AccumulatedCost].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[AccumulatedCost].[ld1_OprSeq] as [ld1_OprSeq], 
	[AccumulatedCost].[JobHead_PartNum] as [JobHead_PartNum], 
	[AccumulatedCost].[ja_PartNum] as [ja_PartNum], 
	[AccumulatedCost].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[AccumulatedCost].[jo_OprSeq] as [jo_OprSeq], 
	(isnull(
    iif(AccumulatedCost.jo_SubContract = 0,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),0
)) as [Calculated_LabTot], 
	(isnull(
    iif(
        AccumulatedCost.Calculated_QtyCompleted = 0,
        AccumulatedCost.jm_TotalCost,
        AccumulatedCost.jm_TotalCost /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0)
    ),
0
)) as [Calculated_MatTot], 
	(isnull(
    iif(
        AccumulatedCost.jo_SubContract = 1,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),
0)) as [Calculated_SCTot], 
	(isnull(
    AccumulatedCost.Calculated_OpActBur /
    nullif(AccumulatedCost.Calculated_QtyCompleted,0),
0)) as [Calculated_BurTot], 
	[AccumulatedCost].[Calculated_MtlQtyCompl] as [Calculated_MtlQtyCompl], 
	[AccumulatedCost].[Calculated_QtyCompleted] as [Calculated_QtyCompleted], 
	[AccumulatedCost].[jo_SubContract] as [jo_SubContract], 
	[AccumulatedCost].[Calculated_OpActLab] as [Calculated_OpActLab], 
	[AccumulatedCost].[Calculated_OpActBur] as [Calculated_OpActBur], 
	[AccumulatedCost].[jm_TotalCost] as [jm_TotalCost], 
	[AccumulatedCost].[JobOper_AssemblySeq] as [JobOper_AssemblySeq], 
	[AccumulatedCost].[JobOper_OprSeq] as [JobOper_OprSeq], 
	[AccumulatedCost].[JobOper_ActLabCost] as [JobOper_ActLabCost], 
	[AccumulatedCost].[JobOper_ActBurCost] as [JobOper_ActBurCost], 
	[AccumulatedCost].[JobOper_SubContract] as [JobOper_SubContract], 
	(sum(AccumulatedCost.JobMtl_TotalCost)) as [Calculated_MtlMatTot], 
	(isnull(
    iif(AccumulatedCost.JobOper_SubContract = 0,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),0
)) as [Calculated_MLabTot], 
	(isnull(
    iif(
        AccumulatedCost.Calculated_MtlQtyCompl = 0,
        AccumulatedCost.JobMtl_TotalCost,
        AccumulatedCost.JobMtl_TotalCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0)
    ),
0
)) as [Calculated_MMatTot], 
	(isnull(
    iif(
        AccumulatedCost.JobOper_SubContract = 1,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),
0)) as [Calculated_MSCTot], 
	(isnull(
    AccumulatedCost.JobOper_ActBurCost /
    nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
0)) as [Calculated_MBurTot] 

from  AccumulatedCost  as [AccumulatedCost]
group by 
	[AccumulatedCost].[ld1_Company], 
	[AccumulatedCost].[ld1_JobNum], 
	[AccumulatedCost].[ld1_AssemblySeq], 
	[AccumulatedCost].[ld1_OprSeq], 
	[AccumulatedCost].[JobHead_PartNum], 
	[AccumulatedCost].[ja_PartNum], 
	[AccumulatedCost].[Calculated_ScrapQty], 
	[AccumulatedCost].[jo_OprSeq], 
	(isnull(
    iif(AccumulatedCost.jo_SubContract = 0,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),0
)), 
	(isnull(
    iif(
        AccumulatedCost.Calculated_QtyCompleted = 0,
        AccumulatedCost.jm_TotalCost,
        AccumulatedCost.jm_TotalCost /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0)
    ),
0
)), 
	(isnull(
    iif(
        AccumulatedCost.jo_SubContract = 1,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),
0)), 
	(isnull(
    AccumulatedCost.Calculated_OpActBur /
    nullif(AccumulatedCost.Calculated_QtyCompleted,0),
0)), 
	[AccumulatedCost].[Calculated_MtlQtyCompl], 
	[AccumulatedCost].[Calculated_QtyCompleted], 
	[AccumulatedCost].[jo_SubContract], 
	[AccumulatedCost].[Calculated_OpActLab], 
	[AccumulatedCost].[Calculated_OpActBur], 
	[AccumulatedCost].[jm_TotalCost], 
	[AccumulatedCost].[JobOper_AssemblySeq], 
	[AccumulatedCost].[JobOper_OprSeq], 
	[AccumulatedCost].[JobOper_ActLabCost], 
	[AccumulatedCost].[JobOper_ActBurCost], 
	[AccumulatedCost].[JobOper_SubContract], 
	(isnull(
    iif(AccumulatedCost.JobOper_SubContract = 0,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),0
)), 
	(isnull(
    iif(
        AccumulatedCost.Calculated_MtlQtyCompl = 0,
        AccumulatedCost.JobMtl_TotalCost,
        AccumulatedCost.JobMtl_TotalCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0)
    ),
0
)), 
	(isnull(
    iif(
        AccumulatedCost.JobOper_SubContract = 1,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),
0)), 
	(isnull(
    AccumulatedCost.JobOper_ActBurCost /
    nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
0)))  as [Main]
where ( Main.ld1_JobNum is not null )
group by 
	[Main].[ld1_JobNum], 
	[Main].[ld1_AssemblySeq], 
	[Main].[ld1_OprSeq], 
	[Main].[JobHead_PartNum], 
	[Main].[ja_PartNum], 
	[Main].[Calculated_ScrapQty], 
	[Main].[jo_OprSeq], 
	[Main].[Calculated_LabTot], 
	[Main].[Calculated_SCTot], 
	[Main].[Calculated_BurTot], 
	[Main].[jo_SubContract], 
	[Main].[JobOper_AssemblySeq], 
	[Main].[JobOper_OprSeq], 
	[Main].[Calculated_MtlMatTot], 
	[Main].[Calculated_MLabTot], 
	[Main].[Calculated_MMatTot], 
	[Main].[Calculated_MSCTot], 
	[Main].[Calculated_MBurTot])  as [MtlTotal]
where ( not isnull(MtlTotal.Calculated_LabTot,0) +
isnull(MtlTotal.Calculated_AllMatTot,0)+
isnull(MtlTotal.Calculated_SCTot,0)+
isnull(MtlTotal.Calculated_BurTot,0) = 0  )

LastWeekScrapCost2.baq (26.4 KB)
EDIT: I just tried doing the SQL import on this SQL, and it generates syntax errors. This is the code right from my BAQ screen. My BAQ runs without errors. ugghh… :roll_eyes:

I’m just responding to the recursion bit of the question, I hope that’s helpful?

Going back to the version that’s doing recursion:

All good so far

	and  child.Parent = parent.AssemblySeq

I don’t have an epicor in front of me at the moment but if JobAsmbl is doing what it says on the tin, all good.

	and  child.AssemblySeq <> parent.AssemblySeq)

Now it looks like you’re trying to do a second recursion. Which would make sense, each assembly can have many subassemblies.

First note: the <> is looking in two directions, and you’re probably wanting to traverse the set of subassemblies in one direction.

Second note: Recursing a two dimensional set needs a little more strategy. It’s possible to bake a sort-by-two-things into its joins and where statements but feels clunky to me and I like to split up headscratchers into smaller steps that are easy to reason about.
If it was me I’d be inclined to sneak in a preceding nonrecursive CTE that selects only job and assembly identifying fields and something like a row_number() over(partition by company, jobnum order by parent, assemblyseq) as foo. Now I have a single incrementing integer sorting everything, and I can recurse like where parent.foo = child.foo + 1.

1 Like

I think this was preventing me from recursively looping over the parent level.

I like your idea, but I’m not sure I can implement it. Adding up the costs for the operations at the assembly level where the scrap occurred is easy. Its getting the related assemblies and operations into the calculation that is the need for the recursion. Breaking up the BAQ into multiple recursive steps seems like a good idea.

Job tables should include everything, you shouldn’t need CTE’s unless they are reaching into other jobs (like sub jobs, or other parts that were built into inventory then issued to this job).

I didn’t read through the whole thread, is that that case?

1 Like


Here is an example. At op 70, ASM 1 is used. So if scrap happens at op 70, it should add up the costs for AMS 0 ops 10-70, and ASM 1 ops 10,20,900. Adding up the top level is easy, but once I try to add in the assembly it blows up this CTE BAQ. I think this is why I need recursion.

This shows the current results of the BAQ for that job:


You can see the costs up through op 70, and then at the far right, you can see the ASM costs. I am so close I just need to add up the highlighted fields.
(Just noticed MtlMat,MMat cost in there twice. Ignore that mistake.)

I think I got it! I would appreciate if anyone provides feedback on this. Until then, I will be using it to estimate cost of scrapped parts.

LastWeekScrapCost2 (1).baq (28.0 KB)

You probably can’t copy/paste this SQL without making a lot of manual fixes, but here it is!

/*  
 * Disclaimer!!! 
 * This is not a real query being executed, but a simplified version for general vision. 
 * Executing it with any other tool may produce a different result. 
 */
with [AssemblyHierarchy] as 
(select  
	[ja].[Company] as [Company], 
	[ja].[JobNum] as [JobNum], 
	[ja].[AssemblySeq] as [AssemblySeq], 
	[ja].[Parent] as [Parent], 
	[JobHead].[PartNum] as [JobHead_PartNum], 
	[ja].[PartNum] as [ja_PartNum], 
	(0) as [Calculated_LevelDepth], 
	(ja.AssemblySeq) as [Calculated_RootAssembly] 

from Erp.JobAsmbl as [ja]
inner join Erp.LaborDtl as [ld] on 
	  ja.Company = ld.Company
	and  ja.JobNum = ld.JobNum
	and  ja.AssemblySeq = ld.AssemblySeq
inner join Erp.JobHead as [JobHead] on 
	  ja.Company = JobHead.Company
	and  ja.JobNum = JobHead.JobNum
where ( ld.ScrapQty > 0  
and ld.PayrollDate >= @FirstDayOfPrevWeek  
and ld.PayrollDate <= @LastDayOfPrevWeek  ))
 ,[Scrap] as 
(select  
	[ld1].[Company] as [ld1_Company], 
	[ld1].[JobNum] as [ld1_JobNum], 
	[ld1].[AssemblySeq] as [ld1_AssemblySeq], 
	[ld1].[OprSeq] as [ld1_OprSeq], 
	(sum(ld1.ScrapQty)) as [Calculated_ScrapQty] 

from Erp.LaborDtl as [ld1]
where ( ld1.ScrapQty > 0  
and ld1.PayrollDate >= @FirstDayOfPrevWeek  
and ld1.PayrollDate <= @LastDayOfPrevWeek  )
group by 
	[ld1].[Company], 
	[ld1].[JobNum], 
	[ld1].[AssemblySeq], 
	[ld1].[OprSeq])
 ,[AccumulatedCost] as 
(select  
	[s].[ld1_Company] as [ld1_Company], 
	[s].[ld1_JobNum] as [ld1_JobNum], 
	[h].[JobHead_PartNum] as [JobHead_PartNum], 
	[s].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[h].[ja_PartNum] as [ja_PartNum], 
	[s].[ld1_OprSeq] as [ld1_OprSeq], 
	[s].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	(isnull(jo.QtyCompleted, 0)) as [Calculated_QtyCompleted], 
	[jo].[OprSeq] as [jo_OprSeq], 
	[jo].[SubContract] as [jo_SubContract], 
	(jo.ActLabCost) as [Calculated_OpActLab], 
	(jo.ActBurCost) as [Calculated_OpActBur], 
	[jm].[TotalCost] as [jm_TotalCost], 
	[JobOper].[AssemblySeq] as [JobOper_AssemblySeq], 
	[JobOper].[OprSeq] as [JobOper_OprSeq], 
	[JobOper].[ActBurCost] as [JobOper_ActBurCost], 
	[JobOper].[ActLabCost] as [JobOper_ActLabCost], 
	[JobOper].[SubContract] as [JobOper_SubContract], 
	[JobMtl].[TotalCost] as [JobMtl_TotalCost], 
	(isnull(JobOper.QtyCompleted, 0)) as [Calculated_MtlQtyCompl], 
	[JobAsmbl].[RelatedOperation] as [JobAsmbl_RelatedOperation], 
	[JobAsmbl].[PartNum] as [JobAsmbl_PartNum], 
	[JobAsmbl1].[RequiredQty] as [JobAsmbl1_RequiredQty] 

from  Scrap  as [s]
inner join  AssemblyHierarchy  as [h] on 
	  s.ld1_Company = h.Company
	and  s.ld1_JobNum = h.JobNum
	and  s.ld1_AssemblySeq = h.AssemblySeq
left outer join Erp.JobOper as [jo] on 
	  h.Company = jo.Company
	and  h.JobNum = jo.JobNum
	and  h.AssemblySeq = jo.AssemblySeq
	and ( jo.OprSeq <= s.ld1_OprSeq  )
left outer join Erp.JobMtl as [jm] on 
	  jo.Company = jm.Company
	and  jo.JobNum = jm.JobNum
	and  jo.AssemblySeq = jm.AssemblySeq
	and  jo.OprSeq = jm.RelatedOperation
left outer join Erp.JobAsmbl as [JobAsmbl] on 
	  jo.Company = JobAsmbl.Company
	and  jo.JobNum = JobAsmbl.JobNum
	and  jo.OprSeq = JobAsmbl.RelatedOperation
	and  (jo.AssemblySeq = JobAsmbl.Child
	or  jo.AssemblySeq = JobAsmbl.Parent)
left outer join Erp.JobOper as [JobOper] on 
	  JobAsmbl.Company = JobOper.Company
	and  JobAsmbl.JobNum = JobOper.JobNum
	and  JobAsmbl.AssemblySeq = JobOper.AssemblySeq
left outer join Erp.JobMtl as [JobMtl] on 
	  JobOper.Company = JobMtl.Company
	and  JobOper.JobNum = JobMtl.JobNum
	and  JobOper.AssemblySeq = JobMtl.AssemblySeq
	and  JobOper.OprSeq = JobMtl.RelatedOperation
inner join Erp.JobAsmbl as [JobAsmbl1] on 
	  jo.Company = JobAsmbl1.Company
	and  jo.JobNum = JobAsmbl1.JobNum
	and  jo.AssemblySeq = JobAsmbl1.AssemblySeq)

select  
	[OldTop].[ld1_JobNum] as [ld1_JobNum], 
	[OldTop].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[OldTop].[ld1_OprSeq] as [ld1_OprSeq], 
	[OldTop].[JobHead_PartNum] as [JobHead_PartNum], 
	[OldTop].[ja_PartNum] as [ja_PartNum], 
	[OldTop].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	(sum(iif(OldTop.JobAsmbl_PartNum<>'',OldTop.Calculated_MLabTot,OldTop.Calculated_LabTot))) as [Calculated_Labor], 
	(sum(iif(OldTop.JobAsmbl_PartNum<>'',OldTop.Calculated_MMatTot,OldTop.Calculated_AllMatTot))) as [Calculated_Materials], 
	(sum(iif(OldTop.JobAsmbl_PartNum<>'',OldTop.Calculated_MSCTot,OldTop.Calculated_SCTot))) as [Calculated_Subcontract], 
	(sum(iif(OldTop.JobAsmbl_PartNum<>'',OldTop.Calculated_MBurTot,OldTop.Calculated_BurTot))) as [Calculated_Burden], 
	((Labor+Materials+Subcontract+Burden)) as [Calculated_TotalCost], 
	(OldTop.Calculated_ScrapQty*TotalCost) as [Calculated_ScrapTotalCost] 

from  (select  
	[MtlTotal].[ld1_JobNum] as [ld1_JobNum], 
	[MtlTotal].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[MtlTotal].[ld1_OprSeq] as [ld1_OprSeq], 
	[MtlTotal].[JobHead_PartNum] as [JobHead_PartNum], 
	[MtlTotal].[ja_PartNum] as [ja_PartNum], 
	[MtlTotal].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[MtlTotal].[jo_OprSeq] as [jo_OprSeq], 
	[MtlTotal].[Calculated_LabTot] as [Calculated_LabTot], 
	[MtlTotal].[Calculated_AllMatTot] as [Calculated_AllMatTot], 
	[MtlTotal].[Calculated_SCTot] as [Calculated_SCTot], 
	[MtlTotal].[Calculated_BurTot] as [Calculated_BurTot], 
	[MtlTotal].[jo_SubContract] as [jo_SubContract], 
	[MtlTotal].[JobOper_AssemblySeq] as [JobOper_AssemblySeq], 
	[MtlTotal].[JobOper_OprSeq] as [JobOper_OprSeq], 
	[MtlTotal].[JobAsmbl_PartNum] as [JobAsmbl_PartNum], 
	[MtlTotal].[Calculated_MLabTot] as [Calculated_MLabTot], 
	[MtlTotal].[Calculated_MMatTot] as [Calculated_MMatTot], 
	[MtlTotal].[Calculated_MSCTot] as [Calculated_MSCTot], 
	[MtlTotal].[Calculated_MBurTot] as [Calculated_MBurTot] 

from  (select  
	[Main].[ld1_JobNum] as [ld1_JobNum], 
	[Main].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[Main].[ld1_OprSeq] as [ld1_OprSeq], 
	[Main].[JobHead_PartNum] as [JobHead_PartNum], 
	[Main].[ja_PartNum] as [ja_PartNum], 
	[Main].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[Main].[jo_OprSeq] as [jo_OprSeq], 
	[Main].[Calculated_LabTot] as [Calculated_LabTot], 
	(sum(Main.Calculated_MatTot)) as [Calculated_AllMatTot], 
	[Main].[Calculated_SCTot] as [Calculated_SCTot], 
	[Main].[Calculated_BurTot] as [Calculated_BurTot], 
	[Main].[jo_SubContract] as [jo_SubContract], 
	[Main].[JobOper_AssemblySeq] as [JobOper_AssemblySeq], 
	[Main].[JobOper_OprSeq] as [JobOper_OprSeq], 
	[Main].[Calculated_MtlMatTot] as [Calculated_MtlMatTot], 
	[Main].[Calculated_MLabTot] as [Calculated_MLabTot], 
	[Main].[Calculated_MMatTot] as [Calculated_MMatTot], 
	[Main].[Calculated_MSCTot] as [Calculated_MSCTot], 
	[Main].[Calculated_MBurTot] as [Calculated_MBurTot], 
	[Main].[JobAsmbl_PartNum] as [JobAsmbl_PartNum] 

from  (select distinct 
	[AccumulatedCost].[ld1_Company] as [ld1_Company], 
	[AccumulatedCost].[ld1_JobNum] as [ld1_JobNum], 
	[AccumulatedCost].[ld1_AssemblySeq] as [ld1_AssemblySeq], 
	[AccumulatedCost].[ld1_OprSeq] as [ld1_OprSeq], 
	[AccumulatedCost].[JobHead_PartNum] as [JobHead_PartNum], 
	[AccumulatedCost].[ja_PartNum] as [ja_PartNum], 
	[AccumulatedCost].[Calculated_ScrapQty] as [Calculated_ScrapQty], 
	[AccumulatedCost].[jo_OprSeq] as [jo_OprSeq], 
	(isnull(
    iif(AccumulatedCost.jo_SubContract = 0,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),0
)) as [Calculated_LabTot], 
	(isnull(
    iif(
        AccumulatedCost.Calculated_QtyCompleted = 0,
        AccumulatedCost.jm_TotalCost / AccumulatedCost.JobAsmbl1_RequiredQty,
        AccumulatedCost.jm_TotalCost /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0)
    ),
0
)) as [Calculated_MatTot], 
	(isnull(
    iif(
        AccumulatedCost.jo_SubContract = 1,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),
0)) as [Calculated_SCTot], 
	(isnull(
    AccumulatedCost.Calculated_OpActBur /
    nullif(AccumulatedCost.Calculated_QtyCompleted,0),
0)) as [Calculated_BurTot], 
	[AccumulatedCost].[Calculated_MtlQtyCompl] as [Calculated_MtlQtyCompl], 
	[AccumulatedCost].[Calculated_QtyCompleted] as [Calculated_QtyCompleted], 
	[AccumulatedCost].[jo_SubContract] as [jo_SubContract], 
	[AccumulatedCost].[Calculated_OpActLab] as [Calculated_OpActLab], 
	[AccumulatedCost].[Calculated_OpActBur] as [Calculated_OpActBur], 
	[AccumulatedCost].[jm_TotalCost] as [jm_TotalCost], 
	[AccumulatedCost].[JobOper_AssemblySeq] as [JobOper_AssemblySeq], 
	[AccumulatedCost].[JobOper_OprSeq] as [JobOper_OprSeq], 
	[AccumulatedCost].[JobOper_ActLabCost] as [JobOper_ActLabCost], 
	[AccumulatedCost].[JobOper_ActBurCost] as [JobOper_ActBurCost], 
	[AccumulatedCost].[JobOper_SubContract] as [JobOper_SubContract], 
	(sum(AccumulatedCost.JobMtl_TotalCost)) as [Calculated_MtlMatTot], 
	(isnull(
    iif(AccumulatedCost.JobOper_SubContract = 0,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),0
)) as [Calculated_MLabTot], 
	(isnull(
    iif(
        AccumulatedCost.Calculated_MtlQtyCompl = 0,
        AccumulatedCost.JobMtl_TotalCost / AccumulatedCost.JobAsmbl1_RequiredQty,
        AccumulatedCost.JobMtl_TotalCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0)
    ),
0
)) as [Calculated_MMatTot], 
	(isnull(
    iif(
        AccumulatedCost.JobOper_SubContract = 1,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),
0)) as [Calculated_MSCTot], 
	(isnull(
    AccumulatedCost.JobOper_ActBurCost /
    nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
0)) as [Calculated_MBurTot], 
	[AccumulatedCost].[JobAsmbl_PartNum] as [JobAsmbl_PartNum] 

from  AccumulatedCost  as [AccumulatedCost]
group by 
	[AccumulatedCost].[ld1_Company], 
	[AccumulatedCost].[ld1_JobNum], 
	[AccumulatedCost].[ld1_AssemblySeq], 
	[AccumulatedCost].[ld1_OprSeq], 
	[AccumulatedCost].[JobHead_PartNum], 
	[AccumulatedCost].[ja_PartNum], 
	[AccumulatedCost].[Calculated_ScrapQty], 
	[AccumulatedCost].[jo_OprSeq], 
	(isnull(
    iif(AccumulatedCost.jo_SubContract = 0,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),0
)), 
	(isnull(
    iif(
        AccumulatedCost.Calculated_QtyCompleted = 0,
        AccumulatedCost.jm_TotalCost / AccumulatedCost.JobAsmbl1_RequiredQty,
        AccumulatedCost.jm_TotalCost /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0)
    ),
0
)), 
	(isnull(
    iif(
        AccumulatedCost.jo_SubContract = 1,
        AccumulatedCost.Calculated_OpActLab /
        nullif(AccumulatedCost.Calculated_QtyCompleted,0),
        0
    ),
0)), 
	(isnull(
    AccumulatedCost.Calculated_OpActBur /
    nullif(AccumulatedCost.Calculated_QtyCompleted,0),
0)), 
	[AccumulatedCost].[Calculated_MtlQtyCompl], 
	[AccumulatedCost].[Calculated_QtyCompleted], 
	[AccumulatedCost].[jo_SubContract], 
	[AccumulatedCost].[Calculated_OpActLab], 
	[AccumulatedCost].[Calculated_OpActBur], 
	[AccumulatedCost].[jm_TotalCost], 
	[AccumulatedCost].[JobOper_AssemblySeq], 
	[AccumulatedCost].[JobOper_OprSeq], 
	[AccumulatedCost].[JobOper_ActLabCost], 
	[AccumulatedCost].[JobOper_ActBurCost], 
	[AccumulatedCost].[JobOper_SubContract], 
	(isnull(
    iif(AccumulatedCost.JobOper_SubContract = 0,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),0
)), 
	(isnull(
    iif(
        AccumulatedCost.Calculated_MtlQtyCompl = 0,
        AccumulatedCost.JobMtl_TotalCost / AccumulatedCost.JobAsmbl1_RequiredQty,
        AccumulatedCost.JobMtl_TotalCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0)
    ),
0
)), 
	(isnull(
    iif(
        AccumulatedCost.JobOper_SubContract = 1,
        AccumulatedCost.JobOper_ActLabCost /
        nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
        0
    ),
0)), 
	(isnull(
    AccumulatedCost.JobOper_ActBurCost /
    nullif(AccumulatedCost.Calculated_MtlQtyCompl,0),
0)), 
	[AccumulatedCost].[JobAsmbl_PartNum])  as [Main]
where ( Main.ld1_JobNum is not null )
group by 
	[Main].[ld1_JobNum], 
	[Main].[ld1_AssemblySeq], 
	[Main].[ld1_OprSeq], 
	[Main].[JobHead_PartNum], 
	[Main].[ja_PartNum], 
	[Main].[Calculated_ScrapQty], 
	[Main].[jo_OprSeq], 
	[Main].[Calculated_LabTot], 
	[Main].[Calculated_SCTot], 
	[Main].[Calculated_BurTot], 
	[Main].[jo_SubContract], 
	[Main].[JobOper_AssemblySeq], 
	[Main].[JobOper_OprSeq], 
	[Main].[Calculated_MtlMatTot], 
	[Main].[Calculated_MLabTot], 
	[Main].[Calculated_MMatTot], 
	[Main].[Calculated_MSCTot], 
	[Main].[Calculated_MBurTot], 
	[Main].[JobAsmbl_PartNum])  as [MtlTotal])  as [OldTop]
group by 
	[OldTop].[ld1_JobNum], 
	[OldTop].[ld1_AssemblySeq], 
	[OldTop].[ld1_OprSeq], 
	[OldTop].[JobHead_PartNum], 
	[OldTop].[ja_PartNum], 
	[OldTop].[Calculated_ScrapQty]

Thanks, Nate for helping out on my BAQ issue today.

Hey, I was messing around the other day with AI and your scrap query.

No profound commentary on CTEs but thought I’d share…

1 Like