SQL查询按月比较产品销量

标签 sql sql-server sql-server-2005 reporting

我有一个每月状态数据库 View ,我需要根据该 View 构建报告。 View 中的数据如下所示:

Category | Revenue  |  Yearh  |  Month
Bikes      10 000      2008        1
Bikes      12 000      2008        2
Bikes      12 000      2008        3
Bikes      15 000      2008        1
Bikes      11 000      2007        2
Bikes      11 500      2007        3
Bikes      15 400      2007        4


...等等

该 View 包含产品类别、收入、年份和月份。我想创建一份比较 2007 年和 2008 年的报告,显示没有销售的月份为 0。所以报告应该看起来像这样:

Category  |  Month  |  Rev. This Year  |  Rev. Last Year
Bikes          1          10 000               0
Bikes          2          12 000               11 000
Bikes          3          12 000               11 500
Bikes          4          0                    15 400


需要注意的关键是第 1 个月仅在 2008 年有销售额,因此 2007 年为 0。此外,第 4 个月仅在 2008 年没有销售额,因此为 0,而它在 2007 年有销售额并且仍然显示。

此外,该报告实际上是针对财政年度的 - 因此,如果 2007 年或 2008 年的第 5 个月没有销售,我希望两列都为 0。

我得到的查询看起来像这样:

SELECT 
    SP1.Program,
    SP1.Year,
    SP1.Month,
    SP1.TotalRevenue,
    IsNull(SP2.TotalRevenue, 0) AS LastYearTotalRevenue

FROM PVMonthlyStatusReport AS SP1 
     LEFT OUTER JOIN PVMonthlyStatusReport AS SP2 ON 
                SP1.Program = SP2.Program AND 
                SP2.Year = SP1.Year - 1 AND 
                SP1.Month = SP2.Month
WHERE 
    SP1.Program = 'Bikes' AND
    SP1.Category = @Category AND 
    (SP1.Year >= @FinancialYear AND SP1.Year <= @FinancialYear + 1) AND
    ((SP1.Year = @FinancialYear AND SP1.Month > 6) OR 
     (SP1.Year = @FinancialYear + 1 AND SP1.Month <= 6))

ORDER BY SP1.Year, SP1.Month

此查询的问题在于,它不会返回上面示例数据中的第四行,因为我们在 2008 年没有任何销售,但我们实际上在 2007 年有销售。

这可能是一个常见的查询/问题,但是我的SQL在做了这么长时间的前端开发后已经生锈了。非常感谢任何帮助!

哦,顺便说一句,我正在使用 SQL 2005 进行此查询,因此如果有任何有用的新功能可能对我有帮助,请告诉我。

最佳答案

Case 语句是我最好的 sql friend 。您还需要一个表格,列出在这两个月内产生 0 转速的时间。

假设基于下表的可用性:

sales: Category | Revenue | Yearh | Month

tm: Year | Month (populated with all dates required for reporting)

示例 1 无空行:

select
    Category
    ,month
    ,SUM(CASE WHEN YEAR = 2008 THEN Revenue ELSE 0 END) this_year
    ,SUM(CASE WHEN YEAR = 2007 THEN Revenue ELSE 0 END) last_year

from
    sales

where
    year in (2008,2007)

group by
    Category
    ,month

返回:

Category  |  Month  |  Rev. This Year  |  Rev. Last Year
Bikes          1          10 000               0
Bikes          2          12 000               11 000
Bikes          3          12 000               11 500
Bikes          4          0                    15 400

示例 2 包含空行: 我将使用子查询(但其他查询可能不会),并将为每个产品和年月组合返回一个空行。

select
    fill.Category
    ,fill.month
    ,SUM(CASE WHEN YEAR = 2008 THEN Revenue ELSE 0 END) this_year
    ,SUM(CASE WHEN YEAR = 2007 THEN Revenue ELSE 0 END) last_year

from
    sales
    Right join (select distinct  --try out left, right and cross joins to test results.
                   product
                   ,year
                   ,month
               from
                  sales --this ideally would be from a products table
                  cross join tm
               where
                    year in (2008,2007)) fill


where
    fill.year in (2008,2007)

group by
    fill.Category
    ,fill.month

返回:

Category  |  Month  |  Rev. This Year  |  Rev. Last Year
Bikes          1          10 000               0
Bikes          2          12 000               11 000
Bikes          3          12 000               11 500
Bikes          4          0                    15 400
Bikes          5          0                    0
Bikes          6          0                    0
Bikes          7          0                    0
Bikes          8          0                    0

请注意,大多数报告工具都会执行此交叉表或矩阵功能,现在我认为 SQL Server 2005 具有枢轴语法,也可以执行此操作。

这里有一些额外的资源。 案件 https://web.archive.org/web/20210728081626/https://www.4guysfromrolla.com/webtech/102704-1.shtml SQL Server 2005 数据透视 http://msdn.microsoft.com/en-us/library/ms177410.aspx

关于SQL查询按月比较产品销量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17194/

相关文章:

java - 在java中从数据库中检索法语字符

sql-server - 在 SQL Server 2005 中,是否有一种简单的方法可以将对象的 "copy"权限从一个用户/角色授予另一个用户/角色?

sql-server-2005 - MSSQLServer 2005中 'server' ,'instance'是什么意思

SQL-Server:关键字 'with' 附近的语法不正确。如果这个语句是一个公用表表达式

sql-server - .Net 压缩和 SQL Server 2005 NVARCHAR(MAX)

sql - postgres 聚合函数调用不能嵌套

mysql - 我们可以在不登录的情况下在远程机器上执行sql查询吗

mysql - 找到可以在任何酒吧找到的最低价格啤酒的名称

sql-server - 有没有办法组合这些查询?

sql-server - 将变量传递给 xp_cmdshell