У меня есть простой SQL Express сервер, и я регистрирую данные на нем, у меня есть несколько машин (промышленное оборудование), которые я контролирую. Всякий раз, когда изменяется состояние компьютеров, я создаю новую запись, которая вводит данные в следующие столбцы. Time (Time Stamp), Machine Name (Текст), Status (1,2 или 3) для запуска, простоя и вниз и ReasonCode (1-10). Мне нужно рассчитать, сколько времени машина находилась в каждом статусе, а также причина для каждого состояния. Я хотел бы сделать это доступным через SQL-отчеты. Это функция, которую LOT промышленных производителей хотят сделать в наши дни, и я пытаюсь создать простой пример. К сожалению, я не так разбираюсь в SQL. Я предполагаю, что это можно поместить в хранимую процедуру и запустить каждые n секунд, чтобы пересчитать. Любая помощь будет оценена по достоинству.Расчет состояния машины в SQL
ответ
Вам не нужно пересчитывать. Вы можете запросить информацию по запросу. Вот самодостаточный пример
DECLARE @Test
Table (
LogTime datetime,
MachineName varchar(100),
Status int ,
ReasonCode int)
INSERT INTO @Test VALUES ('01/01/2011 4:19:11.459' , 'ServerX', 1, 3)
INSERT INTO @Test VALUES ('01/02/2011 3:43:03.652' , 'ServerZ', 0, 4)
INSERT INTO @Test VALUES ('02/04/2011 11:17:51.827' , 'ServerX', 2, 2)
INSERT INTO @Test VALUES ('02/05/2011 4:22:22.205' , 'ServerX', 3, 1)
INSERT INTO @Test VALUES ('01/03/2011 11:42:44.211' , 'ServerZ', 1, 4)
;with TIMEdelta AS (
SELECT
machineName,
t.LogTime,
MIN(nextTime) as nextTime
FROM (
Select
t.MachineName,
t.LogTime,
t1.LogTime nextTime
from @Test t
INNER JOIN @Test t1
ON t.machineName = t1.machineName
AND t.LogTime < t1.LogTime
) t
GROUP BY
machineName,
t.LogTime
)
SELECT
t.MachineName,
t.LogTime,
t.ReasonCode,
t.Status,
DateDiff(DAY, 0, (TIMEdelta.nextTime - TIMEdelta.LogTime)) Days,
DatePart(HOUR , TIMEdelta.nextTime - TIMEdelta.LogTime) Hour,
DatePart(MINUTE, TIMEdelta.nextTime - TIMEdelta.LogTime) MInute
FROM
@Test t
LEFT JOIN TIMEdelta
ON t.LogTime = timedelta.logtime
and t.MachineName = TIMEdelta.MachineName
Это выводит
MachineName LogTime ReasonCode Status Days Hours Minutes
----------- ----------------------- ----------- ----------- ----------- ----------- -----------
ServerX 2011-01-01 04:19:11.460 3 1 34 6 58
ServerZ 2011-01-02 03:43:03.653 4 0 1 7 59
ServerX 2011-02-04 11:17:51.827 2 2 0 17 4
ServerX 2011-02-05 04:22:22.207 1 3 NULL NULL NULL
ServerZ 2011-01-03 11:42:44.210 4 1 NULL NULL NULL
Вы можете изменить выход для отображения текущего времени - logtime вместо Null для тех текущего состояния строк
Update Для агрегаты для стержня вы можете использовать PIVOT
SELECT
MachineName,
[0] as Started,
[1] as Stopped,
[2] as Paused,
[3] as Foo
FROM
(
SELECT
t.MachineName,
t.status,
cast(TimeDelta.nextTime - t.LogTime as DECIMAL(18,10)) duration
FROM
@Test t
LEFT JOIN TIMEdelta
ON t.LogTime = timedelta.logtime
and t.MachineName = TIMEdelta.MachineName
) source
PIVOT
(
SUM(duration)
FOR status IN ([0], [1], [2], [3])
) AS PivotTable;
Который имеет этот выход
MachineName Started Stopped Paused Foo
----------- ------------ -------------- ------------ ------------
ServerX NULL 34.2907449846 0.7114627315 1.0000000000
ServerZ 1.3331082948 NULL NULL ULL
Update Используемые даты, перекрещенные месяцы и обновленные дни известково
Предполагая, что таблица называется status
содержащий
MachineName NVarChar(whatever)
Status Int
Reason Int
Time DateTime
Тогда этот запрос должен работать хорошо
Select
st.MachineName,
st.status,
st.reason
st.Time as TimeChanged,
DateDiff(ss, min(dur.Time), st.Time)
From
Status st inner join
Status dur on st.MachineName = dur.MachineName and st.Time <dur.Time
group by
st.MachineName,
St.Status,
st.Time,
st.reason
Edit - в ответ на ваш комментарий
select
st.MachineName,
sum(case when status=1 then Duration else 0 end) as RunningTime,
sum(case when status=2 then Duration else 0 end) as IdleTime,
sum(case when status=3 then Duration else 0 end) as DownTime,
From
(Select
st.MachineName,
st.status,
st.reason
st.Time as TimeChanged,
DateDiff(ss, min(dur.Time), st.Time) as Duration
From
Status st inner join
Status dur on st.MachineName = dur.MachineName and st.Time <dur.Time
group by
st.MachineName,
St.Status,
st.Time,
st.reason) as foo
Group by MachineName
Это должно получить имя машины и колонки для времени, проведенного в каждом из состояний
+1 Очень хорошее решение. Вы теряете текущее состояние, но его можно получить, по крайней мере, с профсоюзом. –
@Conrad - Хорошая точка. Присоединение может быть изменено на 'left outer', которое должно решить это, датированный даным нулевой аргумент возвращает null. – Robb
Спасибо за вашу помощь, я вижу, как эти работы и я играю с кодом теперь работать, и это так, есть ли способ скомпенсировать все время, когда machien был вверх, без дела и вниз, поэтому я создаю только 3 строки в выходе? как это – Bob
- 1. MATLAB - Расчет машины эпсилон
- 2. Кодирование машины состояния в C++
- 3. моделирование состояния машины для pm
- 4. Состояние машины VHDL пропускает состояния
- 5. Базовая установка состояния машины с использованием состояния без учета состояния
- 6. Jsplump динамическая диаграмма состояния машины
- 7. Генерация событий состояния машины в многопроцессорной архитектуре
- 8. Расчет в SQL
- 9. Расчет процента в SQL
- 10. Расчет Aecc в sql
- 11. Расчет в SQL-заявлении
- 12. Расчет даты в SQL
- 13. Расчет в SQL
- 14. расчет рейтинга в SQL
- 15. Расчет доли в SQL
- 16. Расчет процента в SQL
- 17. Использование Azure Queues как машины состояния
- 18. Переключатель состояния машины на лету Unity C#
- 19. кодирования состояния машины таблицы (Verilog HDL)
- 20. Передача конечного состояния машины и между FSM
- 21. РРР конечных состояния реализации машины Использование VHDL
- 22. расчет времени простоя на основе значений состояния
- 23. Azure python sdk - получение состояния машины
- 24. Непонятный язык для детерминированной машины конечного состояния
- 25. SQL расчет Отставание (MS Access)
- 26. Расчет рабочего времени в SQL
- 27. поворота, как расчет в SQL
- 28. Рекурсивный расчет в SQL (Oracle)
- 29. Сделать расчет в SQL select
- 30. Цена Расчет формулы в SQL
удалить мой ответ, так как он не решает корневой вопрос - я неправильно поняли часть вашего объяснения о ваших типах данных. – JNK