SQL 速度:返回日期范围内的每个日期和每个日期的 count()

我的目标是返回日期范围内的每个日期并计算每个日期的所有记录。

MyTable
-------------------------------
| OrderId |   DateFinalized   |
-------------------------------
|   51    | 2016-1-3 12:50:34 |
|   55    | 2016-1-4 10:01:56 |
|   73    | 2016-1-4 11:52:02 |
|   93    | 2016-1-6 01:35:16 |
|   104   | 2016-1-6 02:40:47 |
-------------------------------

挑战是也包括没有订单的日期。使用MyTable上面,如果日期范围介于2016-1-1之间2016-1-6,则所需的输出将是:

---------------------
|  MyDate  | Orders |
---------------------
| 2016-1-1 |   0    |
| 2016-1-2 |   0    |
| 2016-1-3 |   1    |
| 2016-1-4 |   2    |
| 2016-1-5 |   0    |
| 2016-1-6 |   2    |
---------------------

为此,我使用此查询选择日期,在 1 秒内执行

declare @startdate datetime = '1/1/2016';
declare @enddate datetime = '1/1/2017';

with [dates] as (
    select convert(date, @startdate) as [date] 
    union all
    select dateadd(day, 1, [date])
    from [dates]
    where [date] < @enddate 
)
select 
[date]
from [dates] 
where [date] between @startdate and @enddate
order by [date] desc
option (maxrecursion 0)

当我选择按日期分组的订单数时,如下所示,它也只需要1 秒

declare @startdate datetime = '2/1/2016';
declare @enddate datetime = '1/1/2017';
select 
convert(date,DATEADD(dd, DATEDIFF(dd, 0, datefinalized), 0))  as Dates,
count(OrderID) as OrderCount
from orders 
where datefinalized between @startdate and @enddate
GROUP BY DATEADD(dd, DATEDIFF(dd, 0, datefinalized), 0)
order by DATEADD(dd, DATEDIFF(dd, 0, datefinalized), 0) desc

问题是当我将这两个查询组合在一个 SQL 语句中时。LEFT JOIN执行需要20 秒(!!!)。我尝试了笑声的子查询,但在13 秒时也好不到哪里去

如何有效地连接生成的数据集?

提前感谢您的时间。

SqlZim

使用递归 cte 是生成一系列日期的最糟糕的方法之一。与使用递归 cte 相比,使用堆叠 cte按需生成日期范围要快得多

如果您打算在多行或长时间内使用它,或者您将多次运行此类操作,则最好只创建一个DatesCalendar表。

对于只有 152kb 的内存,你可以在一个表中有 30 年的日期,你可以像这样使用它:

/* 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]);

并像这样查询:

select
    d.[Date]
  , OrderCount = count(o.OrderID)
from dates d
  left join orders o
    on convert(date,o.OrderDate) = d.[Date]
group by d.[Date]
order by d.[Date] desc

数字和日历表参考:


如果你真的不想要日历表,你可以只使用堆叠的 cte 部分:

declare @fromdate date = '20160101';
declare @years    int  = 1;
;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,dateadd(year,@years,@fromdate)))
      [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
    d.[Date]
  , OrderCount = count(o.OrderID)
from dates d
  left join orders o
    on convert(date,o.OrderDate) = d.[Date]
group by d.[Date]
order by d.[Date] desc

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

SQL在日期范围内的分割数

来自分类Dev

Access SQL-在每个记录中仅包含开始的日期范围内进行分配

来自分类Dev

SQL查询每个员工的摘要项目-日期范围

来自分类Dev

SQL Where子句在联接表日期的30天时间范围内返回记录

来自分类Dev

SQL Server在日期范围内的聚合

来自分类Dev

每个状态的SQL显示日期

来自分类Dev

SQL选择日期范围内未包含日期的记录

来自分类Dev

SQL查询来计数日期范围内的项目?

来自分类Dev

Spark SQL-如何对链接到特定日期的日期范围内的值求和

来自分类Dev

SQL计算日期范围内的连续天数

来自分类Dev

SQL显示日期范围内30天内的最接近可用日期

来自分类Dev

强制从SQL查询返回日期范围内的行数

来自分类Dev

SQL返回每个参数售出的10种产品合格的日期

来自分类Dev

SQL:查找具有给定日期范围内每个月的数据的记录

来自分类Dev

Access SQL-在每个记录中仅包含开始的日期范围内进行分配

来自分类Dev

SQL-计算状态在日期范围内保留的日期

来自分类Dev

每个日期的SQL Server CTE

来自分类Dev

SQL选择范围内的日期

来自分类Dev

SQL数据未显示某些日期范围内的数据

来自分类Dev

SQL Where子句在联接表日期的30天时间范围内返回记录

来自分类Dev

SQL查询以生成日期范围内的每月支付日期

来自分类Dev

SQL 查找日期是否在一个范围内

来自分类Dev

如何使 sql 查询在 mysql 中的日期范围内每天返回一行?

来自分类Dev

SQL 在 31 天的时间范围内查找日期

来自分类Dev

SQL COUNT 某个日期的记录数

来自分类Dev

SQL Cross Join 获取日期范围内的所有日期

来自分类Dev

当我在 SQL Server 中在两个日期之间进行选择时,结果是从范围内和范围外一起返回的?

来自分类Dev

SQL - 如何为给定范围内的每个日期选择最新的可用记录

来自分类Dev

SQL 从日期范围内每天获取数据

Related 相关文章

  1. 1

    SQL在日期范围内的分割数

  2. 2

    Access SQL-在每个记录中仅包含开始的日期范围内进行分配

  3. 3

    SQL查询每个员工的摘要项目-日期范围

  4. 4

    SQL Where子句在联接表日期的30天时间范围内返回记录

  5. 5

    SQL Server在日期范围内的聚合

  6. 6

    每个状态的SQL显示日期

  7. 7

    SQL选择日期范围内未包含日期的记录

  8. 8

    SQL查询来计数日期范围内的项目?

  9. 9

    Spark SQL-如何对链接到特定日期的日期范围内的值求和

  10. 10

    SQL计算日期范围内的连续天数

  11. 11

    SQL显示日期范围内30天内的最接近可用日期

  12. 12

    强制从SQL查询返回日期范围内的行数

  13. 13

    SQL返回每个参数售出的10种产品合格的日期

  14. 14

    SQL:查找具有给定日期范围内每个月的数据的记录

  15. 15

    Access SQL-在每个记录中仅包含开始的日期范围内进行分配

  16. 16

    SQL-计算状态在日期范围内保留的日期

  17. 17

    每个日期的SQL Server CTE

  18. 18

    SQL选择范围内的日期

  19. 19

    SQL数据未显示某些日期范围内的数据

  20. 20

    SQL Where子句在联接表日期的30天时间范围内返回记录

  21. 21

    SQL查询以生成日期范围内的每月支付日期

  22. 22

    SQL 查找日期是否在一个范围内

  23. 23

    如何使 sql 查询在 mysql 中的日期范围内每天返回一行?

  24. 24

    SQL 在 31 天的时间范围内查找日期

  25. 25

    SQL COUNT 某个日期的记录数

  26. 26

    SQL Cross Join 获取日期范围内的所有日期

  27. 27

    当我在 SQL Server 中在两个日期之间进行选择时,结果是从范围内和范围外一起返回的?

  28. 28

    SQL - 如何为给定范围内的每个日期选择最新的可用记录

  29. 29

    SQL 从日期范围内每天获取数据

热门标签

归档