我已经接管了一个项目,并且我不知道为什么这段代码在这里。我理解这种观点,但不是正确的,因为它会导致查询在特定点失败。
SELECT pp.productionplanid,
pp.weekstartdate,
pp.weekenddate,
ppi.productionplanitemid,
ppi.soporderreturnlineid,
bat.productionplanbatchid,
sop.documentno,
cust.customeraccountname,
bat.NAME AS BatchName,
si.itemid,
si.code AS StockCode,
si.NAME AS StockName,
sopLine.allocatedquantity,
o.quantity AS LineQty
FROM fuel_productionplan pp
LEFT JOIN fuel_productionplanitem ppi
ON pp.productionplanid = ppi.productionplanid
LEFT JOIN fuel_productionplanbatch ppb
ON ppi.productionplanbatchid = ppb.productionplanbatchid
LEFT JOIN soporderreturnline sopLine
ON ppi.soporderreturnlineid = sopLine.soporderreturnlineid
LEFT JOIN soporderreturn sop
ON sopLine.soporderreturnid = sop.soporderreturnid
LEFT JOIN slcustomeraccount cust
ON sop.customerid = cust.slcustomeraccountid
LEFT JOIN stockitem si
ON sopLine.itemcode = si.code
LEFT JOIN fuel_productionplanbatch bat
ON ppi.productionplanbatchid = bat.productionplanbatchid
LEFT JOIN fuel_boxed boxed
ON sopLine.soporderreturnlineid = boxed.sopitemlineid
AND pp.productionplanid = boxed.productionplanid
CROSS apply (SELECT 1
FROM master..spt_values v
WHERE v.type = 'P'
AND v.number < ( sopLine.allocatedquantity -
Isnull(boxed.qtyboxed, 0) )
) o(quantity)
WHERE sopLine.allocatedquantity > 0
此部分失败,但由于某种原因会影响我的数据,我从未见过master..spt_values之前使用过以下内容。
CROSS apply
(
SELECT 1
FROM master..spt_values v
WHERE v.type = 'P'
AND v.number < (sopline.allocatedquantity - isnull(boxed.qtyboxed, 0))
) o(quantity)
有人可以向我解释什么是spt_values,它是sql服务器中的一个函数,以及如何更好地使用。如果我删除了交叉应用程序,我发现有问题的项目,但我担心V.number在做什么以及为什么原始程序员会用那个吗?
根据建议,我运行了子查询以查看其产生的结果,并产生了以下结果,但我不明白为什么它阻止了我的数据返回。
编辑2
我相信我需要做的只是得到这个结果
(sopLine.AllocatedQuantity - ISNULL(boxed.QtyBoxed, 0))) o(Quantity)
由于LineQty列没有这种复杂性,所以没有一种更简单的方法。
编辑3
当我删除该交叉申请并仅显示两列时,有人可以告诉我交叉联接如何制动返回的数据。
编辑4
当我尝试做以下替换交叉连接的操作时,它不起作用。
sopLine.AllocatedQuantity - boxed.QtyBoxed AS LineQty
编辑5
这是我的替换查询,似乎可以正常工作,但是否安全就可以检查null是否足够。
SELECT pp.ProductionPlanID, pp.WeekStartDate, pp.WeekEndDate, ppi.ProductionPlanItemID, ppi.SOPOrderReturnLineID, bat.ProductionPlanBatchID, sop.DocumentNo,
cust.CustomerAccountName, bat.Name AS BatchName, si.ItemID, si.Code AS StockCode, si.Name AS StockName, sopLine.AllocatedQuantity, boxed.QtyBoxed,
ISNULL(sopLine.AllocatedQuantity - boxed.QtyBoxed, 0) AS LineQty
FROM dbo.FUEL_ProductionPlan AS pp LEFT OUTER JOIN
dbo.FUEL_ProductionPlanItem AS ppi ON pp.ProductionPlanID = ppi.ProductionPlanID LEFT OUTER JOIN
dbo.FUEL_ProductionPlanBatch AS ppb ON ppi.ProductionPlanBatchID = ppb.ProductionPlanBatchID LEFT OUTER JOIN
dbo.SOPOrderReturnLine AS sopLine ON ppi.SOPOrderReturnLineID = sopLine.SOPOrderReturnLineID LEFT OUTER JOIN
dbo.SOPOrderReturn AS sop ON sopLine.SOPOrderReturnID = sop.SOPOrderReturnID LEFT OUTER JOIN
dbo.SLCustomerAccount AS cust ON sop.CustomerID = cust.SLCustomerAccountID LEFT OUTER JOIN
dbo.StockItem AS si ON sopLine.ItemCode = si.Code LEFT OUTER JOIN
dbo.FUEL_ProductionPlanBatch AS bat ON ppi.ProductionPlanBatchID = bat.ProductionPlanBatchID LEFT OUTER JOIN
dbo.FUEL_Boxed AS boxed ON sopLine.SOPOrderReturnLineID = boxed.SopItemLineID AND pp.ProductionPlanID = boxed.ProductionPlanID
WHERE (sopLine.AllocatedQuantity > 0)
尤其是上面的这一行。
ISNULL(sopLine.AllocatedQuantity - boxed.QtyBoxed, 0) AS LineQty
答案 0 :(得分:4)
我自己和Dan
都提到了理货表。最简单(让我们将其称为Numbers
)仅包含一个列(让我们将其称为number
)。该表的每一行都包含一个不同的整数值。在这种情况下,未记录表master..spt_values
中的行的子集将被替换。
因此,创建这样的统计表,查询(如果逻辑正确)现在变为:
CROSS APPLY
(SELECT 1 FROM Numbers
WHERE
Numbers.number < (sopLine.AllocatedQuantity - ISNULL(boxed.QtyBoxed, 0))
) o(Quantity)
(这假设您的理货表从0开始。如果从1开始,请使用<=
而不是<
。如果它也包含负数,请同时添加Numbers.number >=0
作为额外的条件)
正如我在您的问题下方的评论中所说,这里的逻辑似乎是,如果(sopLine.AllocatedQuantity - ISNULL(boxed.QtyBoxed, 0))
是6,我们想cross apply
生成6个行在结果集中,并将其Quantity
的值设置为1。