sql exclut les lignes de décalage

Dans la requête ci-dessous, je souhaite exclure toutes les lignes (factures fournisseur) s'il y a une autre ligne avec le même ID de travail et un total de facture opposé. Par exemple, si le travail 1234 a des factures de fournisseur dans les montants de -10, 10 et 20, alors seul celui avec une valeur de 20 doit être returnné dans les résultats de la requête. Idéalement, si un travail a des factures d'un montant de -10, 10, 10 et 20, les résultats doivent renvoyer la facture 20 et la facture 10 avec la date de facture la plus ancienne.

SELECT J.JobID, VI.VendorInvoiceNo, VI.invoicetotal, VI.importedDate, VI.CreationDate, VI.InvoiceDate FROM VendorInvoices AS VI LEFT JOIN Jobs AS J ON J.JobID = VI.JobID WHERE J.operCompleteDate >= (GETDATE()-90) AND VI.invoicetotal IS NOT NULL AND VI.invoicetotal <> 0 

Votre requête est essentiellement:

 SELECT vi.* FROM VendorInvoices vi LEFT JOIN Jobs J ON J.JobID = VI.JobID WHERE J.operCompleteDate >= (GETDATE()-90) AND vi.invoicetotal IS NOT NULL vi.invoicetotal <> 0; 

Si nous utilisons cela comme un CTE:

 WITH vi as ( SELECT vi.* FROM VendorInvoices vi LEFT JOIN Jobs J ON J.JobID = VI.JobID WHERE J.operCompleteDate >= (GETDATE()-90) AND vi.invoicetotal IS NOT NULL vi.invoicetotal <> 0 ) SELECT vi.* FROM vi WHERE NOT EXISTS (select 1 from vi vi2 where vi2.jobid = vi.jobid and vi2.invoicetotal = - vi.invoicetotal ); 

Pas besoin d'utiliser un CTE pour cela. Cela ne fait qu'append des frais généraux. Il suffit de se référer à la table deux fois dans la requête.

 SELECT J.JobID, VI.VendorInvoiceNo, VI.invoicetotal, VI.importedDate, VI.CreationDate, VI.InvoiceDate FROM VendorInvoices AS VI INNER JOIN Jobs AS J -- Since operCompleteDate must exist, use INNER JOIN ON J.JobID = VI.JobID LEFT JOIN VendorInvoices filter ON filter.JobID = VI.JobID AND filter.InvoiceTotal = -(VI.InvoiceTotal) WHERE J.operCompleteDate >= (GETDATE()-90) AND VI.invoicetotal IS NOT NULL AND filter.invoiceTotal IS NOT NULL AND VI.invoicetotal <> 0 

Un index sur JobID et InvoiceTotal garantira une vitesse de traitement maximale, mais peut ne pas être nécessaire.