Vor diesem
SELECT * FROM T;
+------+------+--------+
| ID | DATE | STATUS |
+------+------+--------+
| 1 | 106 | A |
| 1 | 107 | A |
| 1 | 112 | A |
| 1 | 130 | B |
| 1 | 201 | A |
| 2 | 102 | C |
| 2 | 107 | C |
+------+------+--------+
Es ist ziemlich einfach, einen Block und seqno mit diesen
SELECT T.ID,T.DATE,T.STATUS,
IF(STATUS <> @PREVS,@RN:[email protected]+1,@RN:[email protected]) RNBLOCK ,
IF(STATUS = @PREVS,@RN2:[email protected]+1,@RN2:=1) RNSEQ ,
@PREVS:=STATUS PSTATUS
FROM (SELECT @RN:=1) RNBLOCK, (SELECT @RN2:=0) RNSEQ,(SELECT @PREVS:=NULL) P, T
zu geben, diesen
+------+------+--------+---------+-------+---------+
| ID | DATE | STATUS | RNBLOCK | RNSEQ | PSTATUS |
+------+------+--------+---------+-------+---------+
| 1 | 106 | A | 1 | 1 | A |
| 1 | 107 | A | 1 | 2 | A |
| 1 | 112 | A | 1 | 3 | A |
| 1 | 130 | B | 2 | 1 | B |
| 1 | 201 | A | 3 | 1 | A |
| 2 | 102 | C | 4 | 1 | C |
| 2 | 107 | C | 4 | 2 | C |
+------+------+--------+---------+-------+---------+
So, jetzt zu vergeben haben wir die Blöcke isoliert und wissen die min seq no (1) und die max seqno und wir können sie in eine Tabelle
schieben
drop table t1;
CREATE TABLE `t1` (
`ID` INT(11) NULL DEFAULT NULL,
`DATE` INT(11) NULL DEFAULT NULL,
`STATUS` VARCHAR(1) NULL DEFAULT NULL,
`rnblock` int null default null,
`rnseq` int null default null,
`pstatus` VARCHAR(1) NULL DEFAULT NULL
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;
und eine einfache min max beitreten
SELECT T2.ID,T2.DATE,T3.DATE,T2.STATUS FROM
(
SELECT T1.RNBLOCK,MAX(T1.RNSEQ) MAXSEQ
FROM T1
GROUP BY RNBLOCK
) S
JOIN T1 T2 ON T2.RNBLOCK = S.RNBLOCK AND T2.RNSEQ = 1
JOIN T1 T3 ON T3.RNBLOCK = S.RNBLOCK AND T3.RNSEQ = S.MAXSEQ
erstellen Diesen
+------+------+------+--------+
| ID | DATE | DATE | STATUS |
+------+------+------+--------+
| 1 | 106 | 112 | A |
| 1 | 130 | 130 | B |
| 1 | 201 | 201 | A |
| 2 | 102 | 107 | C |
+------+------+------+--------+
Der Nachteil zu bekommen, ist, dass Sie eine Tabelle erstellen haben, damit es funktioniert.
Oder Sie könnten diese eher plump Code benutzen, die keine Zwischen Tabelle
select u.id,u.date,v.date,u.status from
(
select s.rnblock,s.status,min(s.rnseq) minseq,max(s.rnseq) maxseq
from
(
SELECT T.ID,T.DATE,T.STATUS,
IF(STATUS <> @PREVS,@RN:[email protected]+1,@RN:[email protected]) RNBLOCK ,
IF(STATUS = @PREVS,@RN2:[email protected]+1,@RN2:=1) RNSEQ ,
@PREVS:=STATUS PSTATUS
FROM (SELECT @RN:=1) RNBLOCK, (SELECT @RN2:=0) RNSEQ,(SELECT @PREVS:=NULL) P, T
) s
group by s.rnblock,s.status
) T
join
(SELECT T.ID,T.DATE,T.STATUS,
IF(STATUS <> @PREVS2,@RN3:[email protected]+1,@RN3:[email protected]) RNBLOCK ,
IF(STATUS = @PREVS2,@RN4:[email protected]+1,@RN4:=1) RNSEQ ,
@PREVS2:=STATUS PSTATUS
FROM (SELECT @RN3:=1) RNBLOCK, (SELECT @RN4:=0) RNSEQ,(SELECT @PREVS2:=NULL) P, T
) u on u.rnblock = t.rnblock and u.rnseq = minseq
join
(SELECT T.ID,T.DATE,T.STATUS,
IF(STATUS <> @PREVS3,@RN5:[email protected]+1,@RN5:[email protected]) RNBLOCK ,
IF(STATUS = @PREVS3,@RN6:[email protected]+1,@RN6:=1) RNSEQ ,
@PREVS3:=STATUS PSTATUS
FROM (SELECT @RN5:=1) RNBLOCK, (SELECT @RN6:=0) RNSEQ,(SELECT @PREVS3:=NULL) P, T
) v on v.rnblock = t.rnblock and v.rnseq = maxseq
ich aber über diese für ein bisschen nicht verwendet. Und ich weiß nicht, was in MySQL verfügbar ist (T/SQL hat jetzt Lead- und Lag-Funktionen, die möglicherweise anwendbar sind). Ich konnte mir keine einfache reine SQL-Lösung vorstellen (d. H. Nur Operationen festlegen). Der interative Ansatz ist jedoch geradlinig. Ordnen Sie diese Daten so an, wie Sie sie haben, und durchlaufen Sie sie, und erkennen Sie, wann immer sich die ID oder der Status über die vorherige Zeile ändert. Das hängt von einer Start- oder Endzeit ab oder davon, ob sich der Status oder die ID ändert. Fügen Sie für jeden Übergang eine Zeile in eine neue Tabelle ein. –
können Sie einen Trick mit gespeicherten Prozedur verwenden. –