【问题标题】:How to count databases elements in a range of date?如何计算日期范围内的数据库元素?
【发布时间】:2012-07-09 19:06:02
【问题描述】:

在 SQL Server 过程中,我需要获取与某些约束匹配的所有行(简单的 where 条件),然后按月对它们进行分组。

目标是创建一个图表(在 Sql server 报告服务中),它显示所有数据。

我已经有这样的东西了:

Select Count(*) AS Count, Month(a.issueDate) AS Month, Year(a.issueDate) AS Year
FROM MyTable a
WHERE
....
GROUP BY YEAR(a.issueDate), MONTH(a.issueDate)

我得到了我的数据,我得到了我的图表,但问题是如果我在“MyTable”中没有任何符合我的Where 条件的行,我将没有任何行。

结果是我有一个从一月开始,跳过二月,然后显示三月的图表。

我无法对数据进行后处理,因为它直接连接到 SQL Server Reporting Services 报表。

由于我在大约 20 个存储过程中遇到了这个问题,我会很感激有最简单的方法。

非常感谢您的建议

【问题讨论】:

    标签: sql sql-server reporting-services group-by


    【解决方案1】:

    假设你想要一个特定的年份:

    DECLARE @year INT;
    SET @year = 2012;
    
    DECLARE @start SMALLDATETIME;
    SET @start = DATEADD(YEAR, @year-1900, 0);
    
    ;WITH y AS (SELECT TOP (12) rn = ROW_NUMBER() OVER (ORDER BY [object_id])-1
      FROM sys.all_objects ORDER BY [object_id])
    SELECT DATEADD(MONTH, y.rn, @start), COUNT(t.issueDate)
      FROM y
      LEFT OUTER JOIN dbo.MyTable AS t
      ON t.issueDate >= DATEADD(MONTH, y.rn, @start)
      AND t.issueDate < DATEADD(MONTH, y.rn + 1, @start)
    GROUP BY DATEADD(MONTH, y.rn, @start);
    

    如果它不是特定年份,那么您可以稍微不同地覆盖任何日期范围,只要您提供第 1 个月的第 1 天和上个月的第 1 天(或传递 4 个整数并构造手动日期):

    DECLARE @startdate SMALLDATETIME, @enddate SMALLDATETIME;
    SELECT @startdate = '20111201', @enddate = '20120201';
    
    ;WITH y AS (SELECT TOP (DATEDIFF(MONTH, @startdate, @enddate)+1)
        rn = ROW_NUMBER() OVER (ORDER BY [object_id])-1
        FROM sys.all_objects ORDER BY [object_id]
    )
    SELECT DATEADD(MONTH, y.rn, @startdate), COUNT(t.issueDate)
      FROM y
      LEFT OUTER JOIN dbo.MyTable AS t
      ON t.issueDate >= DATEADD(MONTH, y.rn, @startdate)
      AND t.issueDate < DATEADD(MONTH, y.rn + 1, @startdate)
    GROUP BY DATEADD(MONTH, y.rn, @startdate);
    

    【讨论】:

    • 我的捷径很好:)
    • 似乎很棒,但是有没有办法只在同一年进行迭代?我对这个“With”合成器不太了解,也找不到如何处理“12 月到 2 月”
    • 我试过你的例子,但是,如果我没有任何符合“ON”约束的东西(这个范围内没有元素),我仍然在计数中得到 1(*),因为它是一个 LEFT加入。
    • 问题是,如果我使用“NOT NULL”进行过滤,我遇到了最初的问题,没有为空行返回任何行
    • 我想我找到了一些东西:如果我对连接表上的列执行 COUNT(),如果值为 NULL,我得到 0
    【解决方案2】:

    在报表生成器中,右键单击日期轴,选择属性,然后将轴设置为日期范围,它将为您添加空列,您无需更改 SQL

    【讨论】:

    • 我明天试试 :) 如果可行,那将是更好的解决方案。我只是不知道我是否可以只显示月份+年份而不是日期。
    • 所以我尝试了你的建议,我在 X 轴上有效地得到了几个新标签,但在 Y 轴上没有数据点(甚至没有 0),所以因为它是一个曲线图,我只有在真正存在的点之间有曲线。
    • 由于您没有显示连续数据,您确定曲线是最合适的图表类型吗?
    • 我显示的是连续数据,每个月的元素个数,但是如果我一个月有0个元素,并不意味着它不是连续的。
    • 我相信个别月份是离散的,而不是连续的(你不能有一月半)。
    【解决方案3】:

    您需要构建一个表(此处最好使用 Table 变量),其中包含从最小值到最大值的所有年/月组合。

    然后,您需要将其与您的主查询交叉连接,以便为图表准备好所有年份/月份的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 2016-05-18
      相关资源
      最近更新 更多