了解主SPT值

时间:2018-10-05 12:08:13

标签: sql sql-server

我已经接管了一个项目,并且我不知道为什么这段代码在这里。我理解这种观点,但不是正确的,因为它会导致查询在特定点失败。

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在做什么以及为什么原始程序员会用那个吗?

根据建议,我运行了子查询以查看其产生的结果,并产生了以下结果,但我不明白为什么它阻止了我的数据返回。

enter image description here

编辑2

我相信我需要做的只是得到这个结果

(sopLine.AllocatedQuantity - ISNULL(boxed.QtyBoxed, 0))) o(Quantity) 

由于LineQty列没有这种复杂性,所以没有一种更简单的方法。

编辑3

当我删除该交叉申请并仅显示两列时,有人可以告诉我交叉联接如何制动返回的数据。

enter image description here

编辑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

1 个答案:

答案 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。