2012-12-09 1 views
2

La tâche consiste à sélectionner la sous-catégorie avec le bénéfice minimum par an. La requête suivante, sélectionne quelques sous-catégories par an:La fonction MIN ne fonctionne pas correctement dans une requête SQL compliquée

select 
    min (Profit), 
    CalendarYear, 
    EnglishProductSubcategoryName 
from (
    select 
    SUM(fis.SalesAmount-fis.TotalProductCost) Profit, 
    t.CalendarYear, 
    sc.EnglishProductSubCategoryName 
    from FactInternetSales fis 
    inner join DimProduct p 
      on fis.ProductKey = p.ProductKey 
    inner join DimProductSubcategory sc 
      on p.ProductSubcategoryKey = sc.ProductSubcategoryKey 
    inner join DimTime t 
      on fis.DueDateKey = t.TimeKey 
    group by CalendarYear, EnglishProductSubcategoryName) aa 
    --Order by CalendarYear 
) aa 
group by CalendarYear, EnglishProductSubcategoryName 
order by CalendarYear 
+2

Veuillez expliquer quel est le problème avec la requête que vous avez publiée? comment la fonction 'MIN' ne fonctionne pas correctement? pas la sortie désirée? des erreurs? –

+0

La requête sélectionne par exemple - 2011, 20 000, gants suivant: 2011, 9 000, bottes etc ... Il ne doit y avoir qu'un seul bénéfice de catégorie minimum pour chaque année. –

+1

La façon dont vous avez écrit cette requête, vous obtiendrez ** une valeur MIN() par année et catégorie ** - donc un pour (2011, gants) et un autre pour (2011, Boots) etc - c'est la façon dont vous avez écrit la requête, c'est ainsi que vous récupérez vos données. –

Répondre

1

Si vous voulez trouver la catégorie au profit minimum pour une année donnée, vous avez besoin de réécrire votre requête:

select 
    Profit, 
    CalendarYear, 
    EnglishProductSubcategoryName 
from 
    (.....) aa 
where 
    CalendarYear = 2011 
    AND Profit = (SELECT MIN(Profit) FROM aa WHERE aa.CalendarYear = 2011) 

Cette trouvera la ou les lignes - elles pourraient être multiples - qui ont le profit minimum (pour 2011) tel que rapporté par la sous-requête.

Mise à jour: depuis que vous avez besoin du bénéfice minimum pour chaque année, je réécrivaient probablement tout à fait cette requête à quelque chose comme:

;WITH YearlyProfitsByCategory AS 
(
    SELECT 
     SUM(fis.SalesAmount - fis.TotalProductCost) Profit, 
     t.CalendarYear, 
     sc.EnglishProductSubCategoryName 
    FROM 
     dbo.FactInternetSales fis 
    INNER JOIN 
     dbo.DimProduct p ON fis.ProductKey = p.ProductKey 
    INNER JOIN 
     dbo.DimProductSubcategory sc ON p.ProductSubcategoryKey = sc.ProductSubcategoryKey 
    INNER JOIN 
     dbo.DimTime t ON fis.DueDateKey = t.TimeKey 
    GROUP BY 
     t.CalendarYear, 
     sc.EnglishProductSubCategoryName 
), 
YearlyMinProfits AS 
(
    SELECT 
     CalendarYear, 
     EnglishProductSubCategoryName, 
     Profit, 
     RowNum = ROW_NUMBER() OVER (PARTITION BY CalendarYear ORDER BY Profit) 
    FROM YearlyProfitsByCategory 
) 
SELECT 
    CalendarYear, EnglishProductSubCategoryName, Profit 
FROM YearlyMinProfits 
WHERE RowNum = 1 -- the row with the smallest profit, for every year 

Il utilise un CTE (Common Table Expression) et la fonction de classement ROW_NUMBER() - les deux disponibles dans SQL Server et plus récent (vous n'avez pas mentionné votre version dans votre question)

+0

La requête doit être dynamique ... 2011 était juste un exemple, il peut y avoir 2011, 2012, 2009, années dans le même tableau. –

+0

Si les tables contiennent les années 2008, 2010, 2011 et 2012, le résultat doit contenir 4 lignes. ligne pour chaque année ... –

+0

Great !!!! Merci beaucoup!! Très bonne réponse..! –

Questions connexes