2009-12-30 5 views
0

J'ai une table de base de données avec la structure suivante -SQL pour identifier les valeurs hors tolérance

Week_End  Sales 
2009-11-01 43223.43 
2009-11-08  4324.23 
2009-11-15 64343.23 
... 

Ce que je veux est une instruction SQL qui prendra un début et une date de fin, et d'identifier toutes les lignes dans ce délai lorsque le chiffre d'affaires est supérieur ou inférieur de plus de 3% au chiffre d'affaires moyen pour cette période. Donc, courir contre les données ci-dessus, il retournerait -

Week_End  Sales 
2009-11-08  4324.23 

J'utilise SQL Server 2008, btw.

+0

vos résultats renverraient les 3 valeurs. la limite supérieure est 38415.87 et la plus basse est 36178.05. –

+0

Oui - mon erreur –

Répondre

4

Note: la moyenne dans votre exemple est 37297, de sorte que les trois valeurs de la table finissent par être en dehors de la tolérance.

;with Weeks as --narrows the range to the provided dates 
(
    select * from YourTable 
    where Week_End between @StartDate and @EndDate 
), 
PercentOff as 
(
    select week_end, sales, abs((a.avg - sales)/a.avg) as pct 
    from Weeks 
    cross join (select avg(sales) as avg from Weeks) a 
) 
select * from PercentOff where pct >= .03 
+0

Vous n'avez pas encore résolu le problème. Il veut réduire la moyenne à une période précise, pas toute la table. –

+0

oups, je l'ai mis à jour pour que le CTE prenne un @ StartDate/@ EndDate – dan

+0

Merci dan - point pris sur la moyenne. Ce n'était pas des données de la vie réelle, juste quelques ordures que j'ai tapées. Votre solution est vraiment élégante, parfaite pour ce que je veux. –

2

Quelque chose comme cela devrait fonctionner, remplacer par vos dates ou des paramètres nécessaires

SELECT [Week_End] 
     ,[Sales] 
    FROM [MyTable] 
    WHERE [Week_End] BETWEEN '2009-12-01' AND '2009-12-31' AND 
    Notional NOT BETWEEN 
    .97 * 
     (SELECT AVG(Sales) 
     FROM [MyTable] 
     WHERE [Week_End] BETWEEN '2009-12-01' AND '2009-12-31') 
    AND 
    1.03 *(SELECT AVG(Sales) 
     FROM [MyTable] 
     WHERE [Week_End] BETWEEN '2009-12-01' AND '2009-12-31') 
+0

Il y a un bon cas ici pour l'utilisation de CTE, d'autant plus qu'il utilise SQL Server 2008. –

+0

D'accord, vous pouvez écrire un CTE qui calcule les deux tolérances, puis vous joindre à cela. Laissez-moi voir si je peux le faire fonctionner. – dsolimano

+0

Je pensais à 'SELECT * FROM [MyTable] OERE [Week_End] ENTRE' 2009-12-01 'ET' 2009-12-31 ')' comme le CTE. –

1

Je pense que vous pouvez le faire sans l'auto-jointure en utilisant des fonctions analytiques. Cependant, je ne dispose pas de SQL Server 2008 pour le tester. Essayez ceci:

SELECT * 
FROM (SELECT [Week_End] 
      , [Sales] 
      , AVG([Sales]) OVER() AS [Avg_Sales] 
     FROM [MyTable] 
     WHERE [Week_End] BETWEEN '2009-12-01' AND '2009-12-31') AS s 
WHERE ABS(([Sales] - [Avg_Sales])/[Avg_Sales]) >= 0.03 
Questions connexes