2009-09-30 9 views
0

Il s'agit d'une requête sous-performante que j'ai essayé de simplifier mais que je ne sais pas. Fondamentalement, nous regardons les tables de Dynamics-SL (Solomon) pour déterminer si quelque chose a encore été livré ou non. Souvent, les utilisateurs saisissent la quantité comme ayant été expédiée mais la gestion de l'événement est incorrecte car elle n'a pas réellement quitté l'entrepôt. Donc, nous regardons la table SOEvent pour les éléments avec le type 'NPAK' ou 'PINV' et nous comparons ensuite avec la quantité livrée dans la table SOShipLine ... Problème est nous le faisons encore dans la clause WHERE donc nous nous retrouvons avec ce super requête longue que je dois penser peut être simplifiée, ici il est (TIA):Simplifier l'utilisation multiple de la même séquence CASE WHEN

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) 
+0

C'est une mise en forme Fugly ... –

+0

surtout parce que je viens d'utiliser les 4-espaces-tiret ID comme code au lieu des balises. Pardon. – maczealot

Répondre

1

Désape la clause where et faire la partie supérieure comme une sous-requête.

Ensuite, vous pouvez utiliser une clause where par rapport aux noms de colonnes. Quelque chose comme ceci:

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 
+0

Génial, merci c'est exactement ce que je cherchais mais je ne pouvais pas mettre le doigt dessus! – maczealot

Questions connexes