【问题标题】:SQL - Counting incidents at time period (done) but including another variableSQL - 计算时间段内的事件(完成)但包括另一个变量
【发布时间】:2018-10-20 03:48:55
【问题描述】:

如果代码有点邋遢,我对 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)

要为特定事件拆分这些,我可以将事件 ref 放入 where 子句中,一个作为 =,它会给我那个事件的引擎,一个作为 ,所以它给我剩下的。这一点也有效。

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

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

【问题讨论】:

  • 你总是可以把它扔到一个游标中:) 效率不高,但一关就可以了。
  • 多么绝妙的建议!光标很烂.. 使用数据集的方法
  • rextester.comsqlfiddle.com中的DDL和DML开头

标签: sql-server timestamp temp-tables


【解决方案1】:

使用类似的方法将搜索范围限制在较小的列表中。我刚刚添加并引用了另一个带有过滤器的 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;

我继续重写了您的标量子查询,但我想这只是个人喜好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 2021-05-19
    • 2021-06-30
    相关资源
    最近更新 更多