外部引用来限制内部组
Posted
技术标签:
【中文标题】外部引用来限制内部组【英文标题】:Outer reference to restrict inner group by 【发布时间】:2021-04-15 14:12:13 【问题描述】:我有一系列接收和发出交易。收到的库存可以以每个作业材料项目的不同成本计算,可能在多个交易中收到。并且有两种可能的收货方式:Mfg Receipt 和 Receipt Lines。如果两者都不存在,则成本默认为平均库存成本,该成本可靠地存储在成本类型中。收到的成本没有可靠地存储在问题交易的成本类型中,所以我必须在收据交易中向后搜索。此优先级由 COALESCE 处理。
目的是以收到货时相同的成本将发货退回(反向)到库存。后续收货是可能的,但成本不同,退货应按该成本计算,而不是同一作业中之前或后续收货的成本。
加入成本类型(前缀 int)的事务(前缀 imt)对于 Material ID 21 如下所示:
每个 MaterialIssue 事务都可以与每个 Receipt Lines 配对,因此我必须将内部结果限制为单个接收事务以防止笛卡尔积,没有它,我可以获得多个结果,如材料项 21:
我曾尝试使用 ROW() 排名来完成此 CTE,并使用想象中的所需方法进行评论,但它令人费解,我不知道如何去做:
DECLARE @bShowNonInventory BIT = 1
DECLARE @nCostingMethod INT = 1
DECLARE @vJobID VARCHAR (11) = '23532-02-01'
; WITH
MaterialIssues as (
SELECT
MI.imtJobID JobID
, MI.imtJobAssemblyID AssemblyID
, MI.imtJobMaterialID MaterialID
, SUM(
(
COALESCE(
MR.intActualUnitMaterialCost
, RL.intActualUnitMaterialCost
, intUnitMaterialCost
)
)
* - (intQuantity)
) NetCost
FROM PartTransactions MI -- Material Issue
INNER JOIN PartTransactionCosts
ON imtPartTransactionID = intPartTransactionID
LEFT JOIN /* get single, most recent received cost */
( SELECT * FROM
(
SELECT
imtJobID, imtJobAssemblyID, imtJobMaterialID
, imtPartTransactionID
, intActualUnitMaterialCost
, ROW_Number()
OVER (Partition by imtJobID, imtJobAssemblyID, imtJobMaterialID
Order by imtPartTransactionID DESC) as rn
--^ set of results from ranking too broad
FROM PartTransactionCosts
JOIN PartTransactions
on imtPartTransactionID=intPartTransactionID
WHERE imtTableName='MfgReceipts'
AND intCostType = 4
--< need outer reference here somehow: imtPartTransactionID < (earlier) MI.imtPartTransactionID
) as d
WHERE rn=1
) MR -- Receipt by Mfg Receipt
ON MI.imtJobID=MR.imtJobID
AND MI.imtJobAssemblyID=MR.imtJobAssemblyID
AND MI.imtJobMaterialID=MR.imtJobMaterialID
AND MR.imtPartTransactionID < MI.imtPartTransactionID --< dubious restriction on inner result
LEFT JOIN
( SELECT * FROM
(
SELECT imtJobID, imtJobAssemblyID, imtJobMaterialID
, intActualUnitMaterialCost, imtPartTransactionID
, ROW_Number()
OVER (Partition by imtJobID, imtJobAssemblyID, imtJobMaterialID
Order by imtPartTransactionID DESC) as rn
FROM PartTransactionCosts
JOIN PartTransactions
on imtPartTransactionID=intPartTransactionID
WHERE imtTableName='ReceiptLines'
AND intCostType = 4
--< need outer reference here somehow: imtPartTransactionID < (earlier) MI.imtPartTransactionID
) as d
WHERE rn=1
) RL -- Receipt by ReceiptLine
ON MI.imtJobID=RL.imtJobID
AND MI.imtJobAssemblyID=RL.imtJobAssemblyID
AND MI.imtJobMaterialID=RL.imtJobMaterialID
AND RL.imtPartTransactionID < MI.imtPartTransactionID --< dubious restriction on inner result
WHERE
imtSource = 3
AND imtNonInventoryTransaction <= @bShowNonInventory
AND intCostType = @nCostingMethod
GROUP BY MI.imtJobID
, MI.imtJobAssemblyID
, MI.imtJobMaterialID
)
-- test query:
Select * from
MaterialIssues
WHERE JobID = @vJobID
请注意,此问题与Restricting inner query with outer query atttribute 非常相似 - 但我没有看到将内部集限制为一个最近但不是后续结果的要求。
总而言之,项目 21 的接收和(退货)数量的净结果为零,但净成本也应为零,但不正确。
提前感谢您的建议。
编辑:DDL 和示例数据:
USE [master]
GO
CREATE DATABASE [test]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'test', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\test.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'test_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\test_log.ldf' , SIZE = 199680KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
USE test
CREATE TABLE [test].dbo.[PartTransactions](
[imtPartTransactionID] [int] NOT NULL,
[imtTableName] [nvarchar](30) NOT NULL,
[imtTransactionType] [tinyint] NOT NULL,
[imtSource] [tinyint] NOT NULL,
[imtNonInventoryTransaction] [bit] NOT NULL,
[imtJobID] [nvarchar](20) NOT NULL,
[imtJobAssemblyID] [int] NOT NULL,
[imtJobMaterialID] [int] NOT NULL,
[imtPartID] [nvarchar](30) NOT NULL,
) ON [PRIMARY]
GO
CREATE TABLE [test].[dbo].[PartTransactionCosts](
[intPartTransactionID] [int] NOT NULL,
[intPartTransactionCostID] [int] NOT NULL,
[intCostType] [tinyint] NOT NULL,
[intQuantity] [numeric](15, 5) NOT NULL,
[intUnitMaterialCost] [numeric](15, 5) NOT NULL,
[intActualUnitMaterialCost] [numeric](15, 5) NOT NULL,
) ON [PRIMARY]
GO
-- USE [test]
GO
INSERT [dbo].[PartTransactions] ([imtPartTransactionID], [imtTableName], [imtTransactionType], [imtSource], [imtNonInventoryTransaction], [imtJobID], [imtJobAssemblyID], [imtJobMaterialID], [imtPartID]) VALUES (117718, N'MaterialIssueLines', 2, 3, 0, N'23532-02-01', 0, 21, N'26271/2GC')
GO
INSERT [dbo].[PartTransactions] ([imtPartTransactionID], [imtTableName], [imtTransactionType], [imtSource], [imtNonInventoryTransaction], [imtJobID], [imtJobAssemblyID], [imtJobMaterialID], [imtPartID]) VALUES (117719, N'MfgReceipts', 1, 2, 1, N'23532-02-01', 0, 21, N'26271/2GC')
GO
INSERT [dbo].[PartTransactions] ([imtPartTransactionID], [imtTableName], [imtTransactionType], [imtSource], [imtNonInventoryTransaction], [imtJobID], [imtJobAssemblyID], [imtJobMaterialID], [imtPartID]) VALUES (117726, N'MaterialIssueLines', 2, 3, 0, N'23532-02-01', 0, 21, N'26271/2GC')
GO
INSERT [dbo].[PartTransactions] ([imtPartTransactionID], [imtTableName], [imtTransactionType], [imtSource], [imtNonInventoryTransaction], [imtJobID], [imtJobAssemblyID], [imtJobMaterialID], [imtPartID]) VALUES (117725, N'MfgReceipts', 1, 2, 1, N'23532-02-01', 0, 21, N'26271/2GC')
GO
INSERT [dbo].[PartTransactions] ([imtPartTransactionID], [imtTableName], [imtTransactionType], [imtSource], [imtNonInventoryTransaction], [imtJobID], [imtJobAssemblyID], [imtJobMaterialID], [imtPartID]) VALUES (117727, N'MaterialIssueLines', 2, 3, 0, N'23532-02-01', 0, 21, N'26271/2GC')
GO
INSERT [dbo].[PartTransactions] ([imtPartTransactionID], [imtTableName], [imtTransactionType], [imtSource], [imtNonInventoryTransaction], [imtJobID], [imtJobAssemblyID], [imtJobMaterialID], [imtPartID]) VALUES (117513, N'MfgReceipts', 1, 2, 1, N'23532-02-01', 0, 21, N'26271/2GC')
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117718, 1, 1, CAST(555.00000 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117718, 2, 2, CAST(555.00000 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117718, 3, 3, CAST(555.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117718, 4, 4, CAST(555.00000 AS Numeric(15, 5)), CAST(1.24865 AS Numeric(15, 5)), CAST(1.24865 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117719, 1, 1, CAST(555.00000 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117719, 2, 2, CAST(555.00000 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117719, 3, 3, CAST(555.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117719, 4, 4, CAST(555.00000 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117726, 1, 1, CAST(1100.00000 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117726, 2, 2, CAST(1100.00000 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117726, 3, 3, CAST(1100.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117726, 4, 4, CAST(1100.00000 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117725, 1, 1, CAST(555.00000 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117725, 2, 2, CAST(555.00000 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117725, 3, 3, CAST(555.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117725, 4, 4, CAST(555.00000 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117727, 1, 1, CAST(10.00000 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117727, 2, 2, CAST(10.00000 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117727, 3, 3, CAST(10.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117727, 4, 4, CAST(10.00000 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)), CAST(1.16410 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117513, 1, 1, CAST(555.00000 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)), CAST(1.61513 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117513, 2, 2, CAST(555.00000 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)), CAST(1.53503 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117513, 3, 3, CAST(555.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)), CAST(0.00000 AS Numeric(15, 5)))
GO
INSERT [dbo].[PartTransactionCosts] ([intPartTransactionID], [intPartTransactionCostID], [intCostType], [intQuantity], [intUnitMaterialCost], [intActualUnitMaterialCost]) VALUES (117513, 4, 4, CAST(555.00000 AS Numeric(15, 5)), CAST(1.24865 AS Numeric(15, 5)), CAST(1.24865 AS Numeric(15, 5)))
GO
更新:这是做什么的。
首先,这是来自名为 M1 的 ERP 系统的数据库后端。它的表结构是不可变的。
将材料接收到库存或直接接收到工作是通过“零件交易”完成的。零件交易与 4 种可能的零件交易成本类型之一相结合:1) 平均成本 2) 最后成本(与所讨论的工作无关) 3) 标准成本 4) 实际成本(直接接收到工作中)。使用哪个是由公司范围内的会计政策设置确定的。
平均成本用于从库存发放到作业或从作业返回到库存(未使用)的交易。这是在每次交易时在应用程序代码 (VB) 中计算的。
不涉及库存的材料问题和退货通过各种收据直接接收到作业,例如从采购订单或制造收据(表格:ReceiptLines、MfgReceipt)以及许多其他可能的方法(例如 DMR、 RMI、检验、报废、装运、调整)。这些实体的足迹不同,并且存储在不同的表中。
很遗憾,应用程序代码无法通过收据 (PO) 或制造收据可靠地将“收到的”成本存储到作业中,因此 PartTransactionCost(类型 4,实际)中的数据无法按预期使用。通常它确实计算正确,但神秘的是有时它没有。这是一个错误。
因此,以与任何收据相同的成本从工作中退回材料的唯一可靠方法是从适用的收据记录中获取实际成本。 COALESCE 函数按优先顺序选择非空连接,在没有找到收据的情况下(即所有空结果),最后的成本是平均成本。
在给出的示例数据中,有一张收货 555 数量的物品 21,单位成本为 1.25,然后所有 555 都被退回(即未使用)。这是通过 MaterialIssue 交易完成的(其符号为正,尽管 MaterialIssues 的数量为负),导致净数量为 0,净成本为 0.00。
然后又进行了两次收货,总数量为 1100,但收货单位成本与第一次收货不同。然后又发生了两次退货交易,导致净发行数量再次为 0。但是,我继承的代码并未导致净成本为零,因为简单连接产生了 3 x 3 接收和退货交易的叉积,对于总和中有 9 个分量的虚假结果。所以净退货成本是错误的倍数。很长一段时间都没有注意到这个错误,因为这种交易序列很少见。
必须注意的是,在这个例子中,最后的成本恰好是正确的,但由于它们不能被依赖,我需要从收据记录(表:MfgReceipts)中获取实际收到的成本,而不是从收据中获取transaction. 其他收款类型也需要相同的技术,例如在 ReceiptLines 表中。但只能使用一个收据记录。在所提供的解决方案中,最后收据的实际成本仅返回一次,并用于退货交易以代替存储的“最后成本”——这导致净出库数量为零,净成本为零。
【问题讨论】:
花时间在此处发布minimal reproducible example。那些我们无法消费的大型数据集的图像对于这里的许多用户来说将是一个瞬间的“关闭”。不要将数据发布为图像,将其发布为文本;最好作为 DDL 和 DML 语句。 我正在研究如何做到这一点。 看起来你需要横向连接(T-SQL 中的OUTER APPLY
)。但是您的查询太长而无法深入研究,请弄清楚它是否真的是您需要的并将其写为答案
DDL 和编辑中添加的示例数据。
@JosephShirk 你是什么意思?如果您指的是投票,它们是匿名的;我没有说投票是我的。
【参考方案1】:
解决方案的精髓:
-- solved by example of answer 1-1) at
-- https://***.com/questions/9275132/real-life-example-when-to-use-outer-cross-apply-in-sql
SELECT *
FROM
(SELECT
MI.imtJobID JobID
, MI.imtJobAssemblyID AssemblyID
, MI.imtJobMaterialID MaterialID
, MI.imtPartTransactionID
, intQuantity
FROM PartTransactions MI -- Material Issue
INNER JOIN PartTransactionCosts
ON imtPartTransactionID = intPartTransactionID
WHERE imtSource=3
AND intCostType = 4 -- Average cost, last resort
) MI
OUTER APPLY
(SELECT TOP 1
imtJobID JobID
, imtJobAssemblyID AssemblyID
, imtJobMaterialID MaterialID
, intActualUnitMaterialCost, imtPartTransactionID
, imtTableName, intCostType
FROM PartTransactions PTI JOIN PartTransactionCosts PTCI
on PTI.imtPartTransactionID=PTCI.intPartTransactionID
WHERE imtTableName='MfgReceipts'
AND intCostType = 4
AND PTI.imtJobID=MI.JobID AND PTI.imtJobAssemblyID=MI.AssemblyID AND PTI.imtJobMaterialID=MI.MaterialID
AND PTI.imtPartTransactionID < MI.imtPartTransactionID
-- most recent recieved cost prior to this issuance
ORDER BY PTI.imtPartTransactionID DESC
) MR
order by MI.MaterialID, MI.imtPartTransactionID
并且其结果更容易可视化,因此:
完整实现如下所示:
; WITH
MaterialIssues as (
SELECT
MI.imtJobID JobID
, MI.imtJobAssemblyID AssemblyID
, MI.imtJobMaterialID MaterialID
,
/* abstraction for different job types & sources*/
(
COALESCE(
MR.intActualUnitMaterialCost
, RL.intActualUnitMaterialCost
, intUnitMaterialCost
)
+ intUnitLaborCost
+ intUnitOverheadCost
+ intUnitSubcontractCost
+ intUnitDutyCost
+ intUnitFreightCost
+ intUnitMiscCost
) UnitCost
, intQuantity
Quantity
, imtSource
, imtJobType
, imtNonInventoryTransaction
, imtReceiptID
, imtTableName
FROM PartTransactions MI
INNER JOIN PartTransactionCosts
ON imtPartTransactionID = intPartTransactionID
LEFT JOIN Warehouses
ON imtPartWarehouseLocationID = imwWarehouseID
OUTER APPLY /* get single, most recent receieved cost */
(
SELECT TOP 1
imtJobID JobID, imtJobAssemblyID AssemblyID, imtJobMaterialID MaterialID
, imtPartTransactionID
, intActualUnitMaterialCost
FROM PartTransactionCosts PTCI
JOIN PartTransactions PTI
on imtPartTransactionID=intPartTransactionID
WHERE imtTableName='MfgReceipts'
AND intCostType = 4
AND PTI.imtJobID=MI.imtJobID
AND PTI.imtJobAssemblyID=MI.imtJobAssemblyID
AND PTI.imtJobMaterialID=MI.imtJobMaterialID
AND PTI.imtPartTransactionID < MI.imtPartTransactionID
ORDER BY PTI.imtPartTransactionID DESC
) MR
OUTER APPLY
(
SELECT TOP 1
imtJobID JobID, imtJobAssemblyID AssemblyID, imtJobMaterialID MaterialID
, imtPartTransactionID
, intActualUnitMaterialCost
FROM PartTransactionCosts PTCI
JOIN PartTransactions PTI
on imtPartTransactionID=intPartTransactionID
WHERE imtTableName='ReceiptLines'
AND intCostType = 4
AND PTI.imtJobID=MI.imtJobID
AND PTI.imtJobAssemblyID=MI.imtJobAssemblyID
AND PTI.imtJobMaterialID=MI.imtJobMaterialID
AND PTI.imtPartTransactionID < MI.imtPartTransactionID
ORDER BY PTI.imtPartTransactionID DESC
) RL
WHERE
imtTransactionDate < @dEndDate
AND imtTransactionDate >= @dStartDate
AND (
imtNonNettable = 0
OR (
imtNonNettable <> 0
AND ISNULL(imwDoNotIncludeInJobCosts, 0) = 0
)
)
AND intCostType = @nCostingMethod
/* always 1 */
)
, PartTransactionMaterialCosts as (
SELECT JobID, AssemblyID
, SUM(
UnitCost
*
(
(
CASE
WHEN imtSource = 3
/*MaterialIssueLines*/
THEN - 1
ELSE 1
END
) * Quantity
)
)
NetCost /*NOTE: negated conditionally on Source 3*/
FROM MaterialIssues
WHERE
imtNonInventoryTransaction <= @bShowNonInventory
AND imtSource IN(2, 3)
AND imtJobType IN(1, 3)
AND imtReceiptID = ''
AND Upper(imtTableName) NOT IN ('RECEIPTLINES', 'MFGRECEIPTS', 'MFGRECEIPTCOMPONENTS', 'RECEIPTCOMPONENTS')
GROUP BY JobID, AssemblyID
)
-- test:
Select * from PartTransactionMaterialCosts
【讨论】:
感谢@astentx 为我指明了正确的方向!以上是关于外部引用来限制内部组的主要内容,如果未能解决你的问题,请参考以下文章