1

J'écris une procédure stockée de rapport. Je souhaite obtenir le nombre d'ordres d'achat non-acquittés et non-facturés, avec la possibilité de filtrer (facultativement) sur CustomerID. Ce que j'ai ci-dessous fonctionne comme prévu, mais je crains que a) il est lent et b) il y a une duplication dans la partie CustomerID de la clause WHERE.Reporting Procédure stockée - Comment éviter la duplication?

Comment écrivez-vous ce proc stocké, Stack Overflow?

SELECT 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE AcknowledgmentStatus <> 'Complete' 
    AND (@CustID = 0 OR CustomerID = @CustID) 
) AS NonAckd, 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE InvoiceStatus <> 'Complete' 
    AND (@CustID = 0 OR CustomerID = @CustID) 
) AS NonInvoiced 

Répondre

2

Quelque chose comme ceci:

SELECT Sum(Case When AcknowledgmentStatus <> 'Complete' Then 1 ELSE 0 END) as NonAckd 
     ,Sum(Case When InvoiceStatus <> 'Complete'  Then 1 ELSE 0 END) as NonInvoiced 
    FROM PurchaseOrder 
WHERE CustomerID = IsNull(NullIf(@CustID, 0), CustomerID) 
+0

C'est exactement le genre de chose que je cherchais! Je ne peux pas croire que je n'ai jamais vu cette structure "CASE WHEN". –

2

Je ne suis pas sûr à 100% ce que vous recherchez, mais vous pouvez simplifier la partie client comme suit: (non testé de la mémoire [fatigué])

set @custID = nullif(@custID,0) 

SELECT 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE AcknowledgmentStatus <> 'Complete' 
    AND (CustomerID = isnull(@CustID,CustomerID)) 
) AS NonAckd, 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE InvoiceStatus <> 'Complete' 
    AND (CustomerID = isnull(@CustID,CustomerID)) 
) AS NonInvoiced 
+0

Je pense qu'il veut se débarrasser de la duplication de code trop ... –

+0

Bon usage de NullIf, merci. Je vais ajouter cela à mon dernier proc. –

1

Vous ne pouvez pas utiliser:

  • COUNT parce qu'il se COU nt toutes les lignes (1 ou 0 est non nul il les compte)
  • COUNT DISTINCT donnera 2 (seules les valeurs 1 et 0)

Si vous supprimez les vérifications d'état, il fonctionnera plus rapidement bien sûr si vous peut gérer des zéros.

SELECT 
    CASE WHEN AcknowledgmentStatus <> 'Complete' THEN 1 ELSE 0 END AS NonAckd, 
    CASE WHEN InvoiceStatus <> 'Complete' THEN 1 ELSE 0 END AS NonInvoiced, 
FROM 
    PurchaseOrder 
WHERE 
    (AcknowledgmentStatus <> 'Complete' OR InvoiceStatus <> 'Complete') --optional 
    AND 
    (@CustID = 0 OR CustomerID = @CustID) 
Questions connexes