SQL Server 2014-不同的表交互和SUM

时间:2018-12-06 17:10:25

标签: sql sql-server database sum

简而言之,我有一个数据库,我只需要选择在2008年获利最高的十大最佳产品。(我有一个示例数据库)

我有一个大问题。

这是不完整但有效的代码:

SELECT 
    [AdventureWorksDW2012].[dbo].[FactInternetSales].ProductKey,    
    SUM([AdventureWorksDW2012].[dbo].[FactInternetSales].OrderQuantity) OrderQuantitySum
FROM
    [AdventureWorksDW2012].[dbo].[FactInternetSales]
GROUP BY 
    ProductKey
ORDER BY 
    OrderQuantitySum DESC;

以下是输出:

enter image description here

在数据库中,我有订单和产品,因此基本上可以有ID为15的产品,例如200-300。 我总结了所有订单并将相同的ID分组。

现在,我需要用仅在2008年发生的订单来限制所有内容,我添加了另一个表格,这是代码:

SELECT 
    [AdventureWorksDW2012].[dbo].[FactInternetSales].ProductKey,    
    SUM([AdventureWorksDW2012].[dbo].[FactInternetSales].OrderQuantity) OrderQuantitySum,
    [AdventureWorksDW2012].[dbo].[DimDate].CalendarYear
FROM
    [AdventureWorksDW2012].[dbo].[FactInternetSales], [AdventureWorksDW2012].[dbo].[DimDate]
WHERE 
    CalendarYear = 2008
GROUP BY 
    ProductKey, CalendarYear
ORDER BY 
    OrderQuantitySum DESC;

这是输出:

enter image description here

所以我的订单总额变得异常庞大,我不明白为什么...

我只需要使用仅在2008年发生的订单,而不是减少订单数量,而是令人难以置信的增加。

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

您正在做的是笛卡尔联接,它将返回FactInternetSalesDimDate表中每一行的 ALL 可能组合。您将要如下使用INNER JOIN,并且可以在联接中使用CalendarYear过滤器,而不是添加WHERE子句。作为内部联接,这将仍然限制FactInternetSales中带有2008日历年的行,因为结果集中仅包含该表中DimDate中具有匹配项的行。我没有使用过这些表,但是我猜测它们共享一个DateKey列或类似的列(即,在DimDate中是唯一的并且与FactInternetSales中的列相关的列)。使用表别名代替全名也可以提高可读性。表别名在ORDER BY中不是必需的,因为此列在SELECT中是别名的,而ORDER BY在SELECT之后进行求值,因此OrderQuantitySum名称在此处有效。您的SQL可能看起来与此类似

SELECT 
FIS.ProductKey,
SUM(FIS.OrderQuantity) AS OrderQuantitySum,
DD.CalendarYear
FROM [AdventureWorksDW2012].[dbo].[FactInternetSales] FIS
INNER JOIN [AdventureWorksDW2012].[dbo].[DimDate] DD ON FIS.DateKey = DD.DateKey AND DD.CalendarYear = 2008
GROUP BY FIS.ProductKey, DD.CalendarYear
ORDER BY OrderQuantitySum DESC;