简而言之,我有一个数据库,我只需要选择在2008年获利最高的十大最佳产品。(我有一个示例数据库)
我有一个大问题。
这是不完整但有效的代码:
SELECT
[AdventureWorksDW2012].[dbo].[FactInternetSales].ProductKey,
SUM([AdventureWorksDW2012].[dbo].[FactInternetSales].OrderQuantity) OrderQuantitySum
FROM
[AdventureWorksDW2012].[dbo].[FactInternetSales]
GROUP BY
ProductKey
ORDER BY
OrderQuantitySum DESC;
以下是输出:
在数据库中,我有订单和产品,因此基本上可以有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;
这是输出:
所以我的订单总额变得异常庞大,我不明白为什么...
我只需要使用仅在2008年发生的订单,而不是减少订单数量,而是令人难以置信的增加。
有什么建议吗?
答案 0 :(得分:3)
您正在做的是笛卡尔联接,它将返回FactInternetSales
和DimDate
表中每一行的 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;