0

This is an under-performing query that I've been trying to simplify but am at a loss. Basically we are looking at Dynamics-SL (Solomon) tables to determine if something has shipped yet or not. Often people enter quantity as having shipped yet the event handling is incorrect as it hasn't actually left the warehouse. So we look at the SOEvent table for items with the 'NPAK' or 'PINV' type and then compare against the quantity shipped in the SOShipLine table... Problem is we do this again in the WHERE clause so we end up with this super long query that I gotta think can be simplified, here it is (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)
2
  • That's some Fugly formatting... Commented Sep 30, 2009 at 19:22
  • Mostly because I just used the 4-spaces-indent to ID it as code instead of the tags. Sorry. Commented Sep 30, 2009 at 19:51

1 Answer 1

1

Strip off the where clause and do the top part as a sub-query.

Then you can use a where clause against the column names. Something like this:

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
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks that is exactly what I was looking for but couldn't put my finger on!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.