首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按日计算寄存器,包括零

按日计算寄存器,包括零
EN

Stack Overflow用户
提问于 2017-03-29 19:23:48
回答 2查看 866关注 0票数 1

我在Server数据库中有一个表,其中包含用户每次从我的应用程序下载图像的寄存器,因此我的表TBL_Downloads具有以下结构:

代码语言:javascript
复制
UserID|  ImageID  | DownloadDate              |
------+-----------+---------------------------+
  292 |    782    |  02-01-2016 14:20:22.737  |
  292 |    783    |  02-01-2016 14:20:22.737  |
  292 |    784    |  02-02-2016 14:20:22.737  |
  292 |    785    |  02-04-2016 14:20:22.737  |
  292 |    786    |  02-05-2016 14:20:22.737  |
  292 |    787    |  02-06-2016 14:20:22.737  |

在表中,仅显示了一个特定用户的寄存器,即使有几个寄存器只是为了简化示例。

我想要的是一个结果表,其中包含了过去30天内为特定用户下载的次数,包括没有下载的天数为零。我目前有以下查询:

代码语言:javascript
复制
SELECT COUNT(*) AS Downloads
FROM TBL_Downloads
WHERE DownloadDate BETWEEN DATEADD(day, -30, GETDATE()) AND GETDATE()
  AND IdUser = 292
GROUP BY CAST(DownloadDate AS DATE)

这将返回一个包含sum的表,但只返回至少有一个下载条目的天数。

你知道我该怎么解决这个问题吗?

EN

Stack Overflow用户

回答已采纳

发布于 2017-03-29 19:27:34

您可以使用日历或日期表来处理这类事情。

对于内存中只有152 of的数据,您可以在一个表中有30年的日期,如下所示:

代码语言:javascript
复制
/* dates table */
declare @fromdate date = '20000101';
declare @years    int  = 30;
/* 30 years, 19 used data pages ~152kb in memory, ~264kb on disk */
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
select top (datediff(day, @fromdate,dateadd(year,@years,@fromdate)))
    [Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
into dbo.Dates
from n as deka cross join n as hecto cross join n as kilo
               cross join n as tenK cross join n as hundredK
order by [Date];
create unique clustered index ix_dbo_Dates_date
  on dbo.Dates([Date]);

在不执行创建表的实际步骤的情况下,您可以在公共表表达式中使用该表,如下所示:

代码语言:javascript
复制
declare @fromdate date = dateadd(day  , datediff(day  , 0, getdate() )-30 , 0); 
declare @thrudate date = dateadd(day  , datediff(day  , 0, getdate() ), 0);
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
  select top (datediff(day, @fromdate, @thrudate)+1) 
      [Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
  from n as deka cross join n as hecto cross join n as kilo
                cross join n as tenK cross join n as hundredK
   order by [Date]
)
select [Date]
from dates;

使用以下任何一种方法:

代码语言:javascript
复制
select 
    d.Date
  , count(t.DownloadDate) as DownloadCount
from dates d
  left join TBL_Downloads t
    on d.date = convert(date,t.DownloadDate)
   and t.userid = 292
where d.date >= dateadd(day  , datediff(day  , 0, getdate() )-30 , 0)
  and d.date <= dateadd(day  , datediff(day  , 0, getdate() ), 0)
group by d.date

rextester 演示http://rextester.com/ISK37732 (日期在过去30天内更改)

返回:

代码语言:javascript
复制
+------------+---------------+
|    Date    | DownloadCount |
+------------+---------------+
| 2017-02-27 |             0 |
| 2017-02-28 |             0 |
| 2017-03-01 |             2 |
| 2017-03-02 |             1 |
| 2017-03-03 |             0 |
| 2017-03-04 |             1 |
| 2017-03-05 |             1 |
| 2017-03-06 |             1 |
| 2017-03-07 |             0 |
| 2017-03-08 |             0 |
| 2017-03-09 |             0 |
| 2017-03-10 |             0 |
| 2017-03-11 |             0 |
| 2017-03-12 |             0 |
| 2017-03-13 |             0 |
| 2017-03-14 |             0 |
| 2017-03-15 |             0 |
| 2017-03-16 |             0 |
| 2017-03-17 |             0 |
| 2017-03-18 |             0 |
| 2017-03-19 |             0 |
| 2017-03-20 |             0 |
| 2017-03-21 |             0 |
| 2017-03-22 |             0 |
| 2017-03-23 |             0 |
| 2017-03-24 |             0 |
| 2017-03-25 |             0 |
| 2017-03-26 |             0 |
| 2017-03-27 |             0 |
| 2017-03-28 |             0 |
| 2017-03-29 |             0 |
+------------+---------------+

编号和日历表参考:

票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43102440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档