Sql 同时计算会话数

Sql 同时计算会话数,sql,sql-server,business-intelligence,Sql,Sql Server,Business Intelligence,我正在使用SQL server。 我正在做BI报告,我想计算每个应用程序和国家/地区同时连接的会话总数 我有一个表DimDateTime包含日期和时间的ID DateTimeKey DateTime Date Month MonthName Year Hour 202007010000 2020-07-01 00:00:00.000 2020-07-01 7 juillet 2020

我正在使用SQL server。 我正在做BI报告,我想计算每个应用程序和国家/地区同时连接的会话总数

我有一个表DimDateTime包含日期和时间的ID

DateTimeKey      DateTime                  Date         Month  MonthName  Year        Hour
202007010000    2020-07-01 00:00:00.000    2020-07-01    7    juillet    2020    00:00:00
202007010001    2020-07-01 00:01:00.000    2020-07-01    7    juillet    2020    00:01:00
202007010002    2020-07-01 00:02:00.000    2020-07-01    7    juillet    2020    00:02:00
202007010003    2020-07-01 00:03:00.000    2020-07-01    7    juillet    2020    00:03:00
202007010004    2020-07-01 00:04:00.000    2020-07-01    7    juillet    2020    00:04:00
202007010005    2020-07-01 00:05:00.000    2020-07-01    7    juillet    2020    00:05:00
202007010006    2020-07-01 00:06:00.000    2020-07-01    7    juillet    2020    00:06:00
.....
我有一个名为Application的表和另一个名为Country的表,其中包含应用程序和国家的ID和信息

我有一个包含以下数据的表TestSession:

SessionID |StartDate            | EndDate               | Application_ID | Id_Country 
--------------------------------------------------------------------------------------
1         | 01/06/2020 23:50    |   01/07/2020 06:02    |   1            |  1
2         | 01/06/2020 23:45    |   01/07/2020 00:45    |   1            |  2
3         | 01/06/2020 23:30    |   01/07/2020 01:02    |   2            |  2
4         | 01/06/2020 23:10    |   01/07/2020 00:53    |   2            |  2
5         | 01/06/2020 23:56    |   01/07/2020 10:20    |   1            |  2
6         | 01/06/2020 23:49    |   01/07/2020 02:15    |   1            |  4
7         | 01/06/2020 22:45    |   01/06/2020 23:58    |   2            |  1
8         | 01/06/2020 23:34    |   01/07/2020 00:02    |   2            |  4
9         | 01/07/2020 00:00    |   01/07/2020 03:32    |   2            |  3
10        | 01/07/2020 00:02    |   01/07/2020 02:12    |   1            |  3
....
我想获得特定时间分钟内的连接总数。例如: 应用程序ID 2020/07/01 00:01

Datekey    | Application_ID |   Id_Country | Total_Connections| 
----------------------------------------------------------
202007010001| 1            |   1         | 1
202007010001| 1            |   2         | 2
202007010001| 1            |   3         | 0
202007010001| 1            |   4         | 1
202007010001| 2            |   1         | 0
202007010001| 2            |   2         | 2
202007010001| 2            |   3         | 1
202007010001| 2            |   4         | 1
202007010002| 1            |   1         | 1
202007010003| 1            |   2         | 1

....
我构建了下面的查询,它运行正常。然而,这需要很多时间来处理。 您是否有其他更简单、更快的解决方案? 提前谢谢

声明@datetime; 声明@id_支付int; 声明@id_应用程序int; 声明@max_id_pays int; 声明@max\u id\u应用程序int; 设置为“2020-07-01 00:00:00” 设置@id\u=0 设置@id\u应用程序=0 set@max\u id\u pays=从dbo.TestSession中选择MAXid set@max\u id\u application=从dbo.TestSession中选择MAXid\u int 而@HEU<'2020-07-01 00:01:00' 开始
当@id_支付时,您可以取消打印数据,以便每个日期/时间有一行数据,然后聚合并使用累积总和:

select v.dte, t.Application_ID, t.Id_Country, sum(inc) as inc,
       sum(sum(inc)) over (partition by t.Application_ID, t.Id_Country order by dte) as concurrent_users
from TestSession s cross apply
     (values (s.startdate, 1), (s.enddate, -1)
     ) v(dte, inc)
group by v.dte, t.Application_ID, t.Id_Country
order by v.dte, t.Application_ID, t.Id_Country;

在原始数据中,每个日期/时间有一行。您的结果有一些数字键,但没有解释。当然,这可以按天或其他时间段进一步聚合。

您可以取消对数据的分割,以便每个日期/时间有一行,然后聚合并使用累积总和:

select v.dte, t.Application_ID, t.Id_Country, sum(inc) as inc,
       sum(sum(inc)) over (partition by t.Application_ID, t.Id_Country order by dte) as concurrent_users
from TestSession s cross apply
     (values (s.startdate, 1), (s.enddate, -1)
     ) v(dte, inc)
group by v.dte, t.Application_ID, t.Id_Country
order by v.dte, t.Application_ID, t.Id_Country;

在原始数据中,每个日期/时间有一行。您的结果有一些数字键,但没有解释。当然,这可以按天或其他时间段进一步聚合。

您可以使用右外部联接来获得所需的结果:

SELECT B.*, COALESCE(A.TOTAL, 0) AS TOTAL FROM
 (SELECT Application_ID, Id_Country,
 COUNT(*) AS TOTAL FROM table1 a WHERE StartDate < '2020-01-07 00:01:00'
 AND ENDDATE > '2020-01-07 00:01:00' GROUP BY Application_ID, Id_Country) A
 RIGHT OUTER JOIN
 (SELECT DISTINCT Application_ID, Id_Country FROM table1) B
 ON (A.APPLICATION_ID = B.APPLICATION_ID AND A.Id_Country = B.Id_Country);

您可以使用右外部联接来获得所需的结果:

SELECT B.*, COALESCE(A.TOTAL, 0) AS TOTAL FROM
 (SELECT Application_ID, Id_Country,
 COUNT(*) AS TOTAL FROM table1 a WHERE StartDate < '2020-01-07 00:01:00'
 AND ENDDATE > '2020-01-07 00:01:00' GROUP BY Application_ID, Id_Country) A
 RIGHT OUTER JOIN
 (SELECT DISTINCT Application_ID, Id_Country FROM table1) B
 ON (A.APPLICATION_ID = B.APPLICATION_ID AND A.Id_Country = B.Id_Country);

然而,这需要很多时间来处理。那是因为你用了一段时间。SQL是一种基于集合的语言,在这种基于迭代的解决方案中表现非常糟糕。常用的方法是:将+1分配给登录,将-1分配给注销,并对其应用累积和。datekey与日期/时间值有什么关系?然而,处理它需要花费大量时间。那是因为你用了一段时间。SQL是一种基于集合的语言,在这种基于迭代的解决方案中表现非常糟糕。常用的方法是:分配+1登录,-1注销并对其应用累积和。datekey与日期/时间值有什么关系?谢谢您的评论。然而,我仍然有这个问题。我想给同步用户一个小时的时间。e、 g:如果我在2020/07/01有10个用户登录,其中3个用户的开始时间为17:00,结束时间为17:30。如果我筛选在17:25登录的用户,我希望获得登录3个用户的总用户数的日期和时间。我正在做BI报告。谢谢你的评论。然而,我仍然有这个问题。我想给同步用户一个小时的时间。e、 g:如果我在2020/07/01有10个用户登录,其中3个用户的开始时间为17:00,结束时间为17:30。如果我筛选在17:25登录的用户,我希望获得登录3个用户的总用户数的日期和时间。我正在做BI报告。