2

任务是选择每年利润最低的子类别。下一个查询,每年选择几个子类别:

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 
4

1 回答 1

1

如果要查找给定年份利润最低的类别,则需要重写查询:

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

这将找到子查询报告的具有最低利润(2011 年)的行(可能是多个行)。

更新:由于您需要每年的最低利润,我可能会将此查询完全重写为:

;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

这使用了 CTE(公用表表达式)和ROW_NUMBER()排名函数 - 在 SQL Server 2005和更高版本中都可用(您没有在问题中提及您的版本)

于 2012-12-09T09:27:14.290 回答