返回null

时间:2014-01-30 18:30:33

标签: sql null

我在下面有以下观点。当我使用TOP(1)子句时,第二个嵌套选择总是返回null,但是当我删除此子句时,它会按预期返回数据,只需要多于所需的行数。有没有人能看到任何可以解释这一点的东西?

    SELECT TOP (100) PERCENT
    a.ITEMID AS Model
   ,id.CONFIGID
   ,id.INVENTSITEID AS SiteId
   ,id.INVENTSERIALID AS Serial
   ,it.ITEMNAME AS Description
   ,CASE WHEN it.DIMGROUPID LIKE '%LR-Y' THEN 'Y'
         ELSE 'N'
    END AS SerialNumberReqd
   ,ISNULL(it.PRIMARYVENDORID, N'') AS Vendor
   ,ISNULL(vt.NAME, N'') AS VendorName
   ,id.INVENTLOCATIONID AS Warehouse
   ,id.WMSLOCATIONID AS Bin
   ,ISNULL(CONVERT(varchar(12), CASE WHEN C.DatePhysical < '1901-01-01'
                                     THEN NULL
                                     ELSE C.DatePhysical
                                END, 101), N' ') AS DeliveryDate
   ,CASE WHEN (a.RESERVPHYSICAL > 0
               OR C.StatusIssue = 1)
              AND c.TransType = 0 THEN C.PONumber
         ELSE ''
    END AS SoNumber
   ,'' AS SoDetail
   ,ISNULL(C.PONumber, N'') AS RefNumber
   ,ISNULL(CONVERT(varchar(12), CASE WHEN ins.ProdDate < '1901-01-01'
                                     THEN NULL
                                     ELSE ins.PRODDATE
                                END, 101), N' ') AS DateReceived
   ,it.STKSTORISGROUPID AS ProdGroup
   ,ISNULL(CONVERT(varchar(12), CASE WHEN ins.ProdDate < '1901-01-01'
                                     THEN NULL
                                     ELSE ins.PRODDATE
                                END, 101), N' ') AS ProductionDate
   ,it.ITEMGROUPID
   ,it.STKSTORISGROUPID AS MerchandisingGroup
   ,CASE WHEN a.postedValue = 0
         THEN (CASE WHEN D.CostAmtPosted = 0 THEN D.CostAmtPhysical
                    ELSE D.CostAmtPosted
               END)
         ELSE a.POSTEDVALUE
    END AS Cost
   ,CASE WHEN a.PHYSICALINVENT = 0 THEN a.Picked
         ELSE a.PhysicalInvent
    END AS PhysicalOnHand
   ,ins.STKRUGSQFT AS RugSqFt
   ,ins.STKRUGVENDSERIAL AS RugVendSerial
   ,ins.STKRUGVENDDESIGN AS RugVendDesign
   ,ins.STKRUGEXACTSIZE AS RugExactSize
   ,ins.STKRUGCOUNTRYOFORIGIN AS RugCountryOfOrigin
   ,ins.STKRUGQUALITYID AS RugQualityId
   ,ins.STKRUGCOLORID AS RugColorId
   ,ins.STKRUGDESIGNID AS RugDesignId
   ,ins.STKRUGSHAPEID AS RugShapeId
   ,CASE WHEN (a.AVAILPHYSICAL > 0) THEN 'Available'
         WHEN (id.WMSLOCATIONID = 'NIL') THEN 'Nil'
         WHEN (a.RESERVPHYSICAL > 0)
              AND (c.TransType = 0) THEN 'Committed'
         WHEN (a.RESERVPHYSICAL > 0) THEN 'Reserved'
         WHEN (id.WMSLOCATIONID LIKE '%-Q') THEN 'Damaged'
         WHEN (a.Picked > 0) THEN 'Picked'
         ELSE 'UNKNOWN'
    END AS Status
   ,'' AS ReasonCode
   ,'' AS BaseModel
   ,ISNULL(CAST(ins.STKSTORISCONFIGINFO AS nvarchar(1000)), N'') AS StorisConfigInfo
   ,ISNULL(C.ConfigSummary, N'') AS ConfigSummary
FROM
    dbo.INVENTSUM AS a WITH (NOLOCK)
INNER JOIN dbo.INVENTDIM AS id WITH (NOLOCK)
    ON id.DATAAREAID = a.DATAAREAID
       AND id.INVENTDIMID = a.INVENTDIMID
LEFT OUTER JOIN dbo.INVENTTABLE AS it WITH (NOLOCK)
    ON it.DATAAREAID = a.DATAAREAID
       AND it.ITEMID = a.ITEMID
LEFT OUTER JOIN dbo.VENDTABLE AS vt WITH (NOLOCK)
    ON vt.DATAAREAID = it.DATAAREAID
       AND vt.ACCOUNTNUM = it.PRIMARYVENDORID
LEFT OUTER JOIN dbo.INVENTSERIAL AS ins WITH (NOLOCK)
    ON ins.DATAAREAID = id.DATAAREAID
       AND ins.INVENTSERIALID = id.INVENTSERIALID
LEFT OUTER JOIN (SELECT TOP (1)
                    itt.ITEMID
                   ,invt.INVENTSERIALID
                   ,itt.DATEPHYSICAL AS DatePhysical
                   ,itt.TRANSREFID AS PONumber
                   ,itt.TRANSTYPE AS TransType
                   ,itt.STATUSISSUE AS StatusIssue
                   ,dbo.stkRowsToColumn(itt.INVENTTRANSID, 'STI') AS ConfigSummary
                   ,itt.RECID
                 FROM
                    dbo.INVENTTRANS AS itt WITH (NOLOCK)
                 INNER JOIN dbo.INVENTDIM AS invt WITH (NOLOCK)
                    ON invt.DATAAREAID = itt.DATAAREAID
                       AND invt.INVENTDIMID = itt.INVENTDIMID
                 WHERE
                    (itt.DATAAREAID = 'STI')
                    AND (itt.TRANSTYPE IN (0, 2, 3, 8))
                    AND (invt.INVENTSERIALID <> '')
                 ORDER BY
                    itt.RECID DESC) AS C
    ON C.ITEMID = a.ITEMID
       AND C.INVENTSERIALID = id.INVENTSERIALID
LEFT OUTER JOIN (SELECT TOP (1)
                    itt2.ITEMID
                   ,invt2.INVENTSERIALID
                   ,itt2.COSTAMOUNTPOSTED AS CostAmtPosted
                   ,itt2.COSTAMOUNTPHYSICAL + itt2.COSTAMOUNTADJUSTMENT AS CostAmtPhysical
                   ,itt2.RECID
                 FROM
                    dbo.INVENTTRANS AS itt2 WITH (NOLOCK)
                 INNER JOIN dbo.INVENTDIM AS invt2 WITH (NOLOCK)
                    ON invt2.DATAAREAID = itt2.DATAAREAID
                       AND invt2.INVENTDIMID = itt2.INVENTDIMID
                 WHERE
                    (itt2.DATAAREAID = 'STI')
                    AND (itt2.TRANSTYPE IN (0, 2, 3, 4, 6, 8))
                    AND (invt2.INVENTSERIALID <> '')
                 ORDER BY
                    itt2.RECID DESC) AS D
    ON D.ITEMID = a.ITEMID
       AND D.INVENTSERIALID = id.INVENTSERIALID
WHERE
    (a.DATAAREAID = 'STI')
    AND (a.CLOSED = 0)
    AND (a.PHYSICALINVENT > 0)
    AND (it.ITEMGROUPID LIKE 'FG-%'
         OR it.ITEMGROUPID = 'MULTISHIP')
ORDER BY
    SiteId
   ,Warehouse

2 个答案:

答案 0 :(得分:2)

据推测,子查询中的最高值不符合后续join条件。也就是说,这个条件不符合:

D.ITEMID = a.ITEMID AND D.INVENTSERIALID = id.INVENTSERIALID

您使用的是left outer join,因此会填写NULL个值。

编辑:

重新迭代。当您使用top 1运行它时,没有值(至少对于两个变量的某些组合)。因此,NULL将填入这些值。毕竟,top 1(带括号或不带括号)只返回一行。

当你运行它返回多行时,可能会有匹配。对于匹配的行,将相应的值放入其中。这是left outer join的工作方式。

答案 1 :(得分:0)

戈登的回答是正确的,为什么我在删除顶部时获得了几行,而在我拥有它时没有。有问题的子查询返回了InventTrans表中的所有行(500万+),因此当我使用top时,它只是第一行没有任何东西。当我在TOP子句中尝试随机高值(例如50000)时,我意识到这种情况。

最终解决方法是将C和D子查询中的左外连接更改为Cross Apply,然后更改where子句以更好地过滤表(例如itt.itemid = a.itemid和invt1.inventserialid = id。 inventserialid)。使用它,我能够按预期使用TOP 1.