SQL - подсчет инцидентов за период времени (выполнено), но с другой переменной - PullRequest
0 голосов
/ 10 мая 2018

Я новичок в 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, один как =, чтобы он дал мне двигатели в этом инциденте, и один как <>, чтобы он дал мне остальное. Этот бит тоже работает.

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'

Бит, который я не могу решить, состоит в том, чтобы заставить это работать для нескольких инцидентов, без необходимости вручную изменять ссылку на инцидент в предложении where для всех 300. Ссылки на инциденты, которые я хочу использовать, будут храниться во временной таблице. В идеале я хотел бы выбрать идентификатор, установить переменные @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 голосов
/ 10 мая 2018

Используйте что-то подобное, чтобы ограничить область поиска меньшим списком.Я только что добавил и сослался на другой CTE с фильтром.Если вы хотите параметризовать список, вам понадобится другой подход, например, сначала сохранить эти значения идентификаторов в другой таблице.

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;

Я переписал ваш скалярный подзапрос, но, полагаю, это просто личноепредпочтение.

...