Как объединить две строки данных с предупреждением о выключении и включении питания в одну в Oracle 10g, 11g, MySQL, SQL SERVER (без поддержки MATCH RECOGNIZE) - PullRequest
0 голосов
/ 19 октября 2018

https://drive.google.com/file/d/1yakmTD5M2MEINdBEg2ckUTb3vw7YPFTO/view?usp=sharing

Привет всем,

Я сказал, что данная проблема со ссылкой на ссылку и будет решена с помощью SQL, поддерживается решение для сопоставления с образцом или ORACLE 12C от Wernfried Domscheit's синформация:

CREATE TABLE ALERT_EVENT (MEASUREMENT_POINT VARCHAR2(10), TIME_ALERT DATE, STATUS VARCHAR2(10));

INSERT INTO ALERT_EVENT VALUES('PE01', to_date('04/10/2018 00:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER ON');
INSERT INTO ALERT_EVENT VALUES('PE01', to_date('03/10/2018 00:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER OFF');
INSERT INTO ALERT_EVENT VALUES('PE01', to_date('02/10/2018 00:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER ON');
INSERT INTO ALERT_EVENT VALUES('PE01', to_date('01/10/2018 00:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER OFF');
INSERT INTO ALERT_EVENT VALUES('PE02',  to_date('03/10/2018 00:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER OFF'); 
INSERT INTO ALERT_EVENT VALUES('PE02',  to_date('02/10/2018 23:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER ON');
INSERT INTO ALERT_EVENT VALUES('PE02',  to_date('02/10/2018 22:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER OFF');
INSERT INTO ALERT_EVENT VALUES('PE03', to_date('04/10/2018 10:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER OFF');
INSERT INTO ALERT_EVENT VALUES('PE03',  to_date('02/10/2018 23:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER ON');
INSERT INTO ALERT_EVENT VALUES('PE03',  to_date('02/10/2018 22:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER OFF');
INSERT INTO ALERT_EVENT VALUES('PE03',  to_date('01/10/2018 00:00:00','dd/mm/yyyy hh24:mi:ss'), 'POWER ON');

Результат запроса использовать шаблон сопоставления ORACLE Вы очень близки, попробуйте вот что:

SELECT * 
FROM ALERT_EVENT ml
MATCH_RECOGNIZE (
     PARTITION BY MEASUREMENT_POINT
     ORDER BY TIME_ALERT
     MEASURES  STRT.TIME_ALERT AS start_tstamp,
               LAST(END.TIME_ALERT) AS end_tstamp
     PATTERN (STRT END*)
     DEFINE
        STRT AS STRT.STATUS LIKE '%OFF%' ,
        END AS END.STATUS LIKE '%ON%' 
     ) MR
ORDER BY MEASUREMENT_POINT ,start_tstamp;

MEASUREMENT_POINT   START_TSTAMP           END_TSTAMP
==================  =====================  ====================
PE01                2018-10-01 00:00:00    2018-10-02 00:00:00
PE01                2018-10-03 00:00:00    2018-10-04 00:00:00
PE02                2018-10-02 22:00:00    2018-10-02 23:00:00
PE02                2018-10-03 00:00:00 
PE03                2018-10-02 22:00:00    2018-10-02 23:00:00
PE03                2018-10-04 10:00:00 

Проблема: Но выполнение для более старой версии Oracle или MySQL или SQL Server,SQL для сопоставления с образцом не поддерживается для этой функции.Какое решение для общего запроса по заданным вопросам, не использующее SQL для сопоставления с образцом?

Большое спасибо!

1 Ответ

0 голосов
/ 19 октября 2018

Вы можете сделать это в pre-Oracle 12c, создав новый столбец для группировки, затем найдя min / max time_alerts для соответствующих статусов для точки измерения и нового столбца группировки.

ГруппировкаСтолбец генерируется путем вычисления промежуточной суммы и увеличения ее на 1 каждый раз, когда он обнаруживает состояние ВЫКЛЮЧЕНО.

Это дает нам запрос в следующем виде:

select measurement_point,
       min(case when status = 'POWER OFF' then time_alert end) start_tstamp,
       max(case when status = 'POWER ON' then time_alert end) end_tstamp
from   (select measurement_point,
               time_alert,
               status,
               sum(case when status = 'POWER OFF' then 1 else 0 end) over (partition by measurement_point order by time_alert) grp
        from   alert_event)
group by measurement_point, grp
having min(case when status = 'POWER OFF' then time_alert end) is not null
order by measurement_point, min(time_alert);

MEASUREMENT_POINT START_TSTAMP        END_TSTAMP
----------------- ------------------- -------------------
PE01              01/10/2018 00:00:00 02/10/2018 00:00:00
PE01              03/10/2018 00:00:00 04/10/2018 00:00:00
PE02              02/10/2018 22:00:00 02/10/2018 23:00:00
PE02              03/10/2018 00:00:00 
PE03              02/10/2018 22:00:00 02/10/2018 23:00:00
PE03              04/10/2018 10:00:00 

Обратите внимание, чтоэто сгруппирует последовательные строки со статусом «POWER ON» в одну группу;вам придется поиграть с тем, как генерируется столбец grp, если это не то, что вы хотите.

...