L'opérateur TOP ou OFFSET n'est pas autorisé dans la partie récursive d'une expression de table commune récursive

Je tente de créer une nomenclature chiffrée avec une requête CTE récursive. Le problème que je rencontre est que je dois sélectionner une révision de pièce unique pour les pièces de matériau, mais que les requêtes récursives ne permettent pas l'utilisation de l'opérateur TOP. Pour donner plus d'informations sur le problème:

  • Une révision de pièce (table PartRev) a comme nomenclature composée de plusieurs matériaux (Table PartMtl).
  • Les matériaux d'une nomenclature peuvent également avoir leurs propres matériaux. Pour get ceci, nous avons besoin de la partie matérielle (déjà celle-ci) et de sa révision. Cependant, la révision de la pièce matérielle n'est pas enregistrée par notre système ERP (nous n'avons pas développé le système ERP, donc nous ne pouvons pas le changer). Il est plutôt calculé à la volée et un seul logging sélectionné.
  • SQL Server n'autorise pas l'utilisation de l'opérateur TOP dans la requête récursive, donc je suis incapable de sélectionner une seule révision.

Je ne suis pas sûr de ce que je peux faire pour contourner cela. Ci-dessous le code SQL que j'ai essayé.

WITH CostedBOMFinance AS ( select Erp.PartRev.PartNum, Erp.PartRev.RevisionNum, case when Erp.PartMtl.ViewAsAsm = 1 then 'Asm' else 'Mtl' end as MtlType, Erp.PartMtl.MtlSeq as Seq, Erp.PartMtl.MtlPartNum, ( select TOP(1) Erp.PartRev.RevisionNum from Erp.PartRev as MtlRev where MtlRev.Approved = 1 and MtlRev.PartNum = Erp.PartMtl.MtlPartNum ) as MtlRev, Erp.Part.PartDescription, Erp.PartMtl.QtyPer, Erp.PartMtl.UOMCode, Erp.PartCost.StdBurdenCost, Erp.PartCost.StdLaborCost, Erp.PartCost.StdMaterialCost as StdUnitCost, Erp.PartCost.StdSubContCost, Erp.PartCost.StdBurdenCost + Erp.PartCost.StdLaborCost + Erp.PartCost.StdMaterialCost + Erp.PartCost.StdSubContCost as TotalStdCost, 1 as Level from Erp.PartRev join Erp.PartMtl on Erp.PartMtl.Company = Erp.PartRev.Company and Erp.PartMtl.PartNum = Erp.PartRev.PartNum and Erp.PartMtl.RevisionNum = Erp.PartRev.RevisionNum join Erp.Part on Erp.Part.Company = Erp.PartMtl.Company and Erp.Part.PartNum = Erp.PartMtl.MtlPartNum join Erp.PartCost on Erp.PartCost.Company = Erp.Part.Company and Erp.PartCost.PartNum = Erp.Part.PartNum UNION ALL select Erp.PartRev.PartNum, Erp.PartRev.RevisionNum, case when Erp.PartMtl.ViewAsAsm = 1 then 'Asm' else 'Mtl' end as MtlType, Erp.PartMtl.MtlSeq as Seq, Erp.PartMtl.MtlPartNum, ( select TOP(1) MtlRev.RevisionNum from Erp.PartRev as MtlRev where MtlRev.Approved = 1 and MtlRev.PartNum = Erp.PartMtl.MtlPartNum ) as MtlRev, Erp.Part.PartDescription, Erp.PartMtl.QtyPer, Erp.PartMtl.UOMCode, Erp.PartCost.StdBurdenCost, Erp.PartCost.StdLaborCost, Erp.PartCost.StdMaterialCost as StdUnitCost, Erp.PartCost.StdSubContCost, Erp.PartCost.StdBurdenCost + Erp.PartCost.StdLaborCost + Erp.PartCost.StdMaterialCost + Erp.PartCost.StdSubContCost as TotalStdCost, Level + 1 from Erp.PartRev join Erp.PartMtl on Erp.PartMtl.Company = Erp.PartRev.Company and Erp.PartMtl.PartNum = Erp.PartRev.PartNum and Erp.PartMtl.RevisionNum = Erp.PartRev.RevisionNum join Erp.Part on Erp.Part.Company = Erp.PartMtl.Company and Erp.Part.PartNum = Erp.PartMtl.MtlPartNum join Erp.PartCost on Erp.PartCost.Company = Erp.Part.Company and Erp.PartCost.PartNum = Erp.Part.PartNum join CostedBOMFinance as CostedBOMFinanceParent on CostedBOMFinanceParent.PartNum = Erp.PartMtl.MtlPartNum and CostedBOMFinanceParent.RevisionNum = MtlRev ) select * from CostedBOMFinance 

Vous devez utiliser une fonction de fenêtrage dans ce cas, vous pouvez l'utiliser dans une sous-requête à laquelle vous vous joignez, comme ceci:

 SELECT -- ... MtlRev.RevisionNum, -- ... from Erp.PartRev join ( select RevisionNum, PartNum, ROW_NUMBER() OVER (Partition By PartNum ORDER BY RevisionNum) AS RN from Erp.PartRev as MtlRev where MtlRev.Approved = 1 ) AS MtlRev ON MtlRev.PartNum = Erp.PartMtl.MtlPartNum and MtlRev.RN = 1 -- ... 

Note: il se peut que vous ayez besoin de ORDER BY RevisionNum DESC ou d'une autre command entièrement, je ne sais pas puisque vous ne l'avez pas dit.