SQL - 计算时间段(已完成)的事件,但包括另一个变量

时间:2018-05-09 23:13:57

标签: sql-server timestamp temp-tables

我对SQL很新,很抱歉,如果代码有点邋..

基本上我正在创建一个每小时使用的消防引擎计数,我已经完成了,这一点有效。所以我在过去的五年里都有这个数字。排序。 但是现在我想为一组特定的事件(大约300个)运行它,显示有多少引擎在那个事件,每小时,以及有多少其他同时在使用,但在其他地方。

我的基本工作代码(我从https://stackoverflow.com/a/43337534/5880512修改)如下。它只计算定义时间内的所有P1和P2动员。

DECLARE @startdate datetime = '2018-05-03 00:00:00'
DECLARE @enddate datetime = '2018-05-05 00:00:00'

;with cte as
(
select @startdate startdate
union all
select DATEADD(minute, 60, startdate) 
FROM cte
WHERE DATEADD(minute, 60, startdate) < @enddate
)
select convert(varchar(20), startdate, 120) as CreationTime, (select count(*) FROM MB_MOBILISATIONS WHERE MB_SEND < startdate and MB_LEAVE > startdate And (MB_CALL_SIGN Like '%P1' Or MB_CALL_SIGN Like '%P2')) as Count
from cte
option (maxrecursion 0)

为了解决特定事件的问题,我可以将事件引用到where子句中,一个as =因此它会在那个事件中给我引擎,一个作为&lt;&gt;所以它给了我剩下的。这一点也有效。

select convert(varchar(20), startdate, 120) as CreationTime, (select count(*) FROM MB_MOBILISATIONS WHERE MB_SEND < startdate and MB_LEAVE > startdate And (MB_CALL_SIGN Like '%P1' Or MB_CALL_SIGN Like '%P2') and MB_IN_REF = 1704009991) as 'At Incident'
,   select convert(varchar(20), startdate, 120) as CreationTime, (select count(*) FROM MB_MOBILISATIONS WHERE MB_SEND < startdate and MB_LEAVE > startdate And (MB_CALL_SIGN Like '%P1' Or MB_CALL_SIGN Like '%P2') and MB_IN_REF <> 1704009991) as 'Other Incident'

我无法解决的问题是,这项工作可以用于多个事件,而无需在所有300的where子句中手动更改事件引用。 我想要使​​用的事件引用将存储在临时表中。理想情况下,我希望从事件的开始和结束中选择一个ID,设置变量@startdate和@enddate,然后对该事件的持续时间进行每小时计数。

希望结果看起来像这样

IncidentRef DateTime                At Incident     Other Incident
A           2018-05-03 1:00         4               2
A           2018-05-03 2:00         7               3
A           2018-05-03 3:00         5               3
A           2018-05-03 4:00         2               4
B           2017-03-01 9:00         7               2
B           2017-03-01 10:00        8               3
B           2017-03-01 11:00        6               1
B           2017-03-01 12:00        4               2

我希望这是有道理的。 谢谢:))

1 个答案:

答案 0 :(得分:0)

使用类似的内容将搜索范围限制为较小的列表。我刚刚添加并引用了另一个带过滤器的CTE。如果您希望参数化列表,则需要采用不同的方法,例如首先将这些ID值存储在另一个表中。

with cte as (
    select @startdate startdate
    union all
    select dateadd(minute, 60, startdate) 
    from cte
    where dateadd(minute, 60, startdate) < @enddate
), mobi as (
    select * from MB_MOBILISATIONS
    where MB_IN_REF in (<insert list here>)
)
select convert(varchar(20), startdate, 120) as CreationTime, m."Count"
from cte cross apply (
    select count(*) as "Count" from mobi
    where MB_SEND < startdate and MB_LEAVE > startdate and
        (MB_CALL_SIGN like '%P1' or MB_CALL_SIGN like '%P2')
) m;

我继续改写你的标量子查询,但我想这只是个人偏好。