问题描述
|
抱歉,这个问题的标题不好吗?我不确定我能否简要描述它,所以这里是详细版本:
我正在尝试生成报告,实际上我不确定我想做的事情是否可以完全在SQL语句中完成。我想要的输出将是这样的:
Product X
January: 1 sold
February : 0 sold
Product Y
January : 0 sold
February: 1 sold
这是基本的SQL语句(顺便说一句,必须针对SQL Server 2000和2008运行-不用问):
SELECT p.productName,SUM(s.salesID) AS numSold,MONTH(s.salesDate) AS monthSold
FROM sales s
LEFT JOIN products p ON s.productID = p.productID
WHERE s.saleDate > \'1/1/2011\'
AND s.saleDate < \'2/28/2011\'
GROUP BY p.productName
ORDER BY p.productName,MONTH(s.salesDate)
据我所知,问题是该SQL语句(正确)在没有销售的任何月份都不会为month + sales的组合返回一行。但是为了使实际输出此数据变得容易,我真正需要的是该语句为不包含任何数据的任何产品+月返回一些值(理想情况下为0,但不一定是)。
因此,查询现在返回的是:
productX January 1
ProductY February 1
...我希望它返回的是:
productX January 1
productX February 0
productY January 0
productY February 1
看来这是我应该能够做的事情。我尝试过这样的事情:
SELECT p.productName,ISNULL(SUM(s.salesID),-100) AS numSold,MONTH(s.salesDate) AS monthSold
...但是,也许可以预见,这没有用。
救命? (-;
解决方法
看看这个最近的问题/答案:SQL查询按月计数
如果您有一个月表,则可以将其用作基表。您将获得每个月的记录。
,我见过这样的情况,您可以假设在分组的报告期内至少发生了某件事
因此,假设任何产品每月至少要进行一次销售,您可以提取月份和年份并生成一个序列,然后针对合并的销售进行LEFT JOIN。
这可能并非在所有情况下都有效(例如每天分组),但假设您每月至少卖出一件东西似乎很合理。
另外,不是COUNT不是SUM吗?
SELECT
p.productName,COUNT(s.salesID) AS numSold,series.aMonth AS monthSold,series.aYear AS yearSold
FROM
(
SELECT DISTINCT
MONTH(salesDate) AS aMonth,YEAR(salesDate) AS aYear
FROM sales
WHERE saleDate > \'1/1/2011\'
AND saleDate < \'2/28/2011\'
) series
LEFT JOIN
sales s ON series.aMonth = MONTH(s.salesDate) AND series.aYear = YEAR(s.salesDate)
LEFT JOIN
products p ON s.productID = p.productID
GROUP BY
p.productName,series.aMonth,series.aYear
ORDER BY
p.productName,series.aYear
对于SQL Server 2000+也可以
,第一次“回答”我自己的一个问题,如果我搞砸了,就此道歉,但是...
正如我在@gbn \的评论中提到的那样,@ gbn和@Fosco都提供了可行的解决方案。他们是:
在数据库中创建一个日历表,并引用该表
通过使用@Fosco的建议或诸如CTE之类的“性感”东西(我无法使用,因为CTE是在SQL Server 2005中引入的)即时创建一个“ calendar \”表。
所以我认为我有需要的东西。希望这对其他人也有帮助。