Упростите многократное использование одной и той же последовательности CASE WHEN - PullRequest
0 голосов
/ 30 сентября 2009

Это неэффективный запрос, который я пытался упростить, но затрудняюсь. В основном мы смотрим на таблицы Dynamics-SL (Solomon), чтобы определить, что-то уже отправлено или нет. Часто люди вводят количество как отгруженное, но обработка событий некорректна, поскольку она фактически не покинула склад. Итак, мы смотрим в таблицу SOEvent для элементов с типом «NPAK» или «PINV», а затем сравниваем их с количеством, отгруженным в таблицу 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 Ответ

1 голос
/ 30 сентября 2009

Удалите предложение 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...