鑑於這種
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 |
+------+------+--------+
這是很簡單的使用這個
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
爲了給這個
+------+------+--------+---------+-------+---------+
| 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 |
+------+------+--------+---------+-------+---------+
所以,現在我們已經分離塊,知道分配塊的SeqNo min seq no(1)和max seqno,我們可以將它們推入表格
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
;
,並創建一個簡單的最小值最大值加入
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
得到這個
+------+------+------+--------+
| ID | DATE | DATE | STATUS |
+------+------+------+--------+
| 1 | 106 | 112 | A |
| 1 | 130 | 130 | B |
| 1 | 201 | 201 | A |
| 2 | 102 | 107 | C |
+------+------+------+--------+
的缺點是,你必須創建一個表,使其工作。
或者你可以使用這個相當笨拙的代碼不使用中間表
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
不過,我覺得這個對位。因爲我不知道MySQL中有什麼可用的聲明和哨聲(T/SQL現在具有可能適用的前導和滯後函數)。我想不出一個直接的純粹的SQL解決方案(即只有集合操作)。然而,交互方法是直截了當的。按照您擁有的方式對數據進行排序,然後遍歷它,並檢測以前的行ID或狀態是否更改。這是開始或結束時間取決於狀態或ID是否正在改變。在每個轉換的新表格中插入一行。 –
你可以使用一些使用存儲過程的技巧。 –