简化多次使用相同的CASE WHEN序列

时间:2009-09-30 19:07:55

标签: sql

这是一个表现欠佳的查询,我一直在努力简化,但我不知所措。基本上我们正在研究Dynamics-SL(所罗门)表来确定某些东西是否已经发货。通常人们输入数量已经发货但事件处理不正确,因为它实际上没有离开仓库。因此,我们查看具有'NPAK'或'PINV'类型的项目的SOEvent表,然后与SOShipLine表中的数量进行比较...问题是我们在WHERE子句中再次这样做,所以我们最终得到这个超级我想要的长查询可以简化,这里是(TIA):

SELECT     

SOHeader.OrdNbr, 
SOHeader.CustID, 
SOHeader.User9 AS ShipDate,
SOLine.LineRef, 
SOLine.InvtID, 
SOLine.QtyOrd, 

CASE WHEN SOShipHeader.InvcNbr = '' THEN

CASE WHEN (
            SELECT MIN(EventTime)  
            FROM  Solomon_SOEvent SOEvent WITH (NOLOCK)   
            WHERE  (SOEvent.EventType = 'NPAK' OR SOEvent.EventType = 'PINV') 
            AND SOEvent.OrdNbr = SOHeader.OrdNbr) IS NULL 
THEN 0 

ELSE (
        SELECT MAX(SOShipLine.QtyShip) 
        FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
        WHERE SOShipLine.InvtID = SOLine.InvtID 
        AND SOShipLine.SiteID = SOLine.SiteID 
        AND SOShipHeader.ShipperID = SOShipLine.ShipperID
        )
END 

ELSE
  ISNULL(
        (SELECT MAX(SOShipLine.QtyShip) 
         FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
         WHERE SOShipLine.InvtID = SOLine.InvtID 
         AND SOShipLine.SiteID = SOLine.SiteID
         AND SOShipHeader.ShipperID = SOShipLine.ShipperID)
,0)

END

AS QtyShip_Corrected,

ISNULL(
    (SELECT MAX(SOShipLine.QtyShip) 
     FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
     WHERE SOShipLine.InvtID = SOLine.InvtID 
     AND SOShipLine.SiteID = SOLine.SiteID 
     AND SOShipHeader.ShipperID = SOShipLine.ShipperID)
   ,0)

AS SOShipLineQtyShip,

QtyShip

FROM Solomon_SOHeader SOHeader  WITH (NOLOCK) 
INNER JOIN Solomon_SOLine SOLine  WITH (NOLOCK) ON SOHeader.OrdNbr = SOLine.OrdNbr 
INNER JOIN Solomon_SOShipHeader SOShipHeader  WITH (NOLOCK) ON SOShipHeader.OrdNbr = SOHeader.OrdNbr 
AND SOShipHeader.Cancelled = 0

WHERE SOHeader.Status = 'O'
AND SOLine.QtyShip > 0
AND CASE WHEN SOShipHeader.InvcNbr = '' 

THEN

CASE WHEN (
        SELECT     MIN(EventTime)  
        FROM  Solomon_SOEvent SOEvent WITH (NOLOCK)   
        WHERE (SOEvent.EventType = 'NPAK' OR SOEvent.EventType = 'PINV') 
        AND SOEvent.OrdNbr = SOHeader.OrdNbr) IS NULL 
THEN 0 

    ELSE (
            SELECT MAX(SOShipLine.QtyShip) 
            FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
            WHERE SOShipLine.InvtID = SOLine.InvtID 
            AND SOShipLine.SiteID = SOLine.SiteID 
            AND SOShipHeader.ShipperID = SOShipLine.ShipperID
         )
    END 
ELSE

    ISNULL(
            (SELECT MAX(SOShipLine.QtyShip) 
             FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
             WHERE SOShipLine.InvtID = SOLine.InvtID 
             AND SOShipLine.SiteID = SOLine.SiteID 
             AND SOShipHeader.ShipperID = SOShipLine.ShipperID)
       ,0)

END 

  <> ISNULL(
            (SELECT MAX(SOShipLine.QtyShip) 
             FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
             WHERE SOShipLine.InvtID = SOLine.InvtID 
             AND SOShipLine.SiteID = SOLine.SiteID 
             AND SOShipHeader.ShipperID = SOShipLine.ShipperID)
    ,0)

1 个答案:

答案 0 :(得分:1)

剥离where子句并将顶部作为子查询。

然后,您可以对列名使用where子句。像这样:

select * 
from  (
    SELECT     
        SOHeader.OrdNbr, 
        SOHeader.CustID, 
        SOHeader.User9 AS ShipDate,
        SOLine.LineRef, 
        SOLine.InvtID, 
        SOLine.QtyOrd, 

        CASE WHEN SOShipHeader.InvcNbr = '' THEN
            CASE WHEN (
                            SELECT MIN(EventTime)  
                            FROM  Solomon_SOEvent SOEvent WITH (NOLOCK)   
                        WHERE  (SOEvent.EventType = 'NPAK' OR SOEvent.EventType = 'PINV') 
                        AND SOEvent.OrdNbr = SOHeader.OrdNbr) IS NULL 
                THEN 0 

                ELSE (
                        SELECT MAX(SOShipLine.QtyShip) 
                        FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
                    WHERE SOShipLine.InvtID = SOLine.InvtID 
                    AND SOShipLine.SiteID = SOLine.SiteID 
                    AND SOShipHeader.ShipperID = SOShipLine.ShipperID
                    )
            END 

            ELSE
              ISNULL(
                    (SELECT MAX(SOShipLine.QtyShip) 
                     FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
                     WHERE SOShipLine.InvtID = SOLine.InvtID 
                     AND SOShipLine.SiteID = SOLine.SiteID
                     AND SOShipHeader.ShipperID = SOShipLine.ShipperID)
            ,0)
        END
        AS QtyShip_Corrected,

        ISNULL(
            (SELECT MAX(SOShipLine.QtyShip) 
             FROM Solomon_SOShipLine SOShipLine WITH (NOLOCK) 
             WHERE SOShipLine.InvtID = SOLine.InvtID 
             AND SOShipLine.SiteID = SOLine.SiteID 
             AND SOShipHeader.ShipperID = SOShipLine.ShipperID)
           ,0)

        AS SOShipLineQtyShip,1

        QtyShip

    FROM Solomon_SOHeader SOHeader  WITH (NOLOCK) 
    INNER JOIN Solomon_SOLine SOLine  WITH (NOLOCK) ON SOHeader.OrdNbr = SOLine.OrdNbr 
    INNER JOIN Solomon_SOShipHeader SOShipHeader  WITH (NOLOCK) ON SOShipHeader.OrdNbr = SOHeader.OrdNbr 
    AND SOShipHeader.Cancelled = 0

    WHERE SOHeader.Status = 'O'
    AND SOLine.QtyShip > 0
) a
where QtyShip_Corrected <> SOShipLineQtyShip