如何选择和计算过去30天的记录,如果某一天没有记录,则在计数中显示0

时间:2017-05-11 20:19:10

标签: sql sql-server

我有一张桌子,根据处理的时刻或日期存储一些记录。

我需要为过去30天创建一个图表,所以如果在任何给定的日子里没有记录我需要0,那么图形将绘制0并且不会忽略该特定日期。< / p>

到目前为止,这是我已经完成的事情,但它只会给我一些有记录的日子:

SELECT
    CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE) AS [Fecha],
    COUNT(*) AS [Regs]
FROM [dbo].[N_Insc_Preg_Control]

WHERE
    [dbo].[N_Insc_Preg_Control].[FechaInscFn] >= DATEADD(DAY, DATEDIFF(DAY,0,CURRENT_TIMESTAMP)- 7,0)

GROUP BY
    CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE) 

这会返回:

Fecha | REGS

2017-05-04 | 5

2017-05-05 | 2

2017-05-07 | 3

2017-05-08 | 7

因此,过去30天所有日子都没有表格......我需要所有那些日子出现在那张桌子上,但是在0

有关如何实现这一点的任何提示???

谢谢!

3 个答案:

答案 0 :(得分:1)

假设您count已经existing Query

这就像上面的给定Sample Data一样:

DECLARE @StartDate datetime
DECLARE @EndDate datetime
set @StartDate = DATEADD(MONTH,-1,GETDATE())
set @EndDate = GETDATE()

--Your Given Query or Sample Data here
declare @tb table (fetcha date,Regs int)
insert into @tb
select '2017-05-04' as Fetcha, 5 as Regs union all
select '2017-05-05' , 2 union all
select '2017-05-07' , 3 union all
select '2017-05-08' , 7
--End of your given Query

;WITH cte1 (S) AS (
SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (S)
),
cte2 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte1 AS cte2),
cte3 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte2 AS cte2)

select result as fetcha,CASE WHEN Regs IS NULL THEN 0 ELSE Regs end as Regs from
(select distinct cast(result as date) result from
(SELECT TOP (DATEDIFF(day, @StartDate, @EndDate) + 1)
        result = DATEADD(day, ROW_NUMBER() OVER(ORDER BY S) - 1, @StartDate)
FROM cte3) as res) as list_of_dates

left join

(select fetcha,Regs from @tb where fetcha >=@StartDate and fetcha<=@EndDate) as dt_fromTable
on list_of_dates.result = dt_fromTable.fetcha

输出过去30天后:

--Fetcha---Regs--
2017-04-12  0
2017-04-13  0
2017-04-14  0
2017-04-15  0
2017-04-16  0
2017-04-17  0
2017-04-18  0
2017-04-19  0
2017-04-20  0
2017-04-21  0
2017-04-22  0
2017-04-23  0
2017-04-24  0
2017-04-25  0
2017-04-26  0
2017-04-27  0
2017-04-28  0
2017-04-29  0
2017-04-30  0
2017-05-01  0
2017-05-02  0
2017-05-03  0
2017-05-04  5
2017-05-05  2
2017-05-06  0
2017-05-07  3
2017-05-08  7
2017-05-09  0
2017-05-10  0
2017-05-11  0
2017-05-12  0

答案 1 :(得分:0)

您可以生成最近一个月的日期,并按以下方式交叉申请: 我修改了你的查询

SELECT
    CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE) AS [Fecha],
    COUNT(*) AS [Regs] --or sum of values
FROM [dbo].[N_Insc_Preg_Control]
cross apply
(
    select top(datediff(day, dateadd(month,-1,CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE)), CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE))+1) dt = dateadd(day, ( row_number() over(order by (select null)) - 1), dateadd(month,-1,CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE))) from master..spt_values s1, master..spt_values s2
) q
WHERE
    [dbo].[N_Insc_Preg_Control].[FechaInscFn] >= DATEADD(DAY, DATEDIFF(DAY,0,CURRENT_TIMESTAMP)- 7,0)
GROUP BY
    CAST([dbo].[N_Insc_Preg_Control].[FechaInscFn] AS DATE) 

答案 2 :(得分:0)

您应该使用日历表加入您的查询,如果您没有这样的表,您可以在过去30天内生成这样的表:

    with nums as 
    (
    select number as n 
    from master..spt_values
    where type = 'p'
    and number between 1 and 30
    )

    ,calendar as
    (
    select dateadd(day, -n, cast(getdate() as date)) as dt
    from nums
    )

    select ...
    from calendar c left join...