2015-01-09 111 views
0

我有一個表具有以下數據MySQL的:計數最大序列長度

(1995, 'a'), 
(1996, 'a'), 
(1997, 'a'), 
(1998, 'a'), 
(2000, 'a'), 

(1995, 'b'), 
(1997, 'b'), 
(1998, 'b'), 

(1995, 'c'), 
(1999, 'c'), 
(2000, 'c'), 

(1999, 'd'), 

(1999, 'e'), 

(1999, 'f'); 

我需要計數最大序列長度的每個字母,例如:因爲「A」在1995,1996存在時, 1997,1998連續「a」的最大序列長度爲4.預期輸出爲:

a-4 
b-2 
c-2 
d-1 
e-1 
f-1 

不確定如何繼續。

感謝

+0

您需要定義「連續」(至少,關於應查找哪個字段)SQL中不存在「自然連續」這樣的事物 - 記錄不是自己排序的,它們可能只是有序的在某些選擇查詢結果集中 - 因此,它必須由某個字段完成 – 2015-01-09 18:26:30

+0

@AlmaDo在這種情況下是不確定的。所有需要定義的內容都已定義。 – Strawberry 2015-01-09 18:27:36

+0

@AlmaDo「連續」基於上述示例中的「年」字段 – ak111in 2015-01-09 18:28:43

回答

2

考慮以下幾點:

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table (year INT NOT NULL,string CHAR(1) NOT NULL,PRIMARY KEY(year,string)); 

INSERT INTO my_table VALUES 
    (1995, 'a'), 
    (1996, 'a'), 
    (1997, 'a'), 
    (1998, 'a'), 
    (2000, 'a'), 

    (1995, 'b'), 
    (1997, 'b'), 
    (1998, 'b'), 

    (1995, 'c'), 
    (1999, 'c'), 
    (2000, 'c'), 

    (1999, 'd'), 

    (1999, 'e'), 

    (1999, 'f'); 

SELECT string 
    , MAX(diff) FROM 
    (SELECT a.string 
      , a.year start 
      , MIN(c.year) end 
      , MIN(c.year) - a.year+1 diff 
     FROM my_table a 
     LEFT 
     JOIN my_table b 
      ON b.string = a.string 
      AND b.year + 1 = a.year 
     LEFT 
     JOIN my_table c 
      ON c.string = a.string 
      AND c.year >= a.year 
     LEFT 
     JOIN my_table d 
      ON d.string = a.string 
      AND d.year - 1 = c.year 
     WHERE b.string IS NULL 
      AND c.string IS NOT NULL 
      AND d.string IS NULL 
     GROUP 
      BY a.string,a.year 
    ) a 
GROUP 
    BY string; 

+--------+-----------+ 
| string | MAX(diff) | 
+--------+-----------+ 
| a  |   4 | 
| b  |   2 | 
| c  |   2 | 
| d  |   1 | 
| e  |   1 | 
| f  |   1 | 
+--------+-----------+ 

編輯:我有一個審美的反感變量,但說實話,在這裏表現而言,他們更高效...

SELECT string 
    , MAX(i) 
    FROM 
    (
     SELECT year 
      , string 
      , IF([email protected]_year+1,IF([email protected]_string,@i:[email protected]+1,@i:=1),@i:=1)i 
      , @prev_year := year 
      , @prev_string := string 
     FROM my_table 
      , (SELECT @prev_year=0,@prev_string:='',@i:=1) vars 
     ORDER 
      BY string 
      , year 
    ) x 
GROUP 
    BY string; 
+--------+--------+ 
| string | MAX(i) | 
+--------+--------+ 
| a  |  4 | 
| b  |  2 | 
| c  |  2 | 
| d  |  1 | 
| e  |  1 | 
| f  |  1 | 
+--------+--------+ 
+0

謝謝你完美的工作 – ak111in 2015-01-09 18:45:48

+0

我在我的服務器上嘗試了大約30K條記錄,而mysql只是凍結了,是否有可能改變查詢,使它適用於大型數據集。 – ak111in 2015-01-09 20:09:26

+0

使用變量的解決方案可能會表現更好。請參閱編輯。 – Strawberry 2015-01-10 00:59:49

0

我想下面的代碼會幫助你,

SELECT string, COUNT(string) AS MAX 
FROM my_table 
GROUP BY string 
HAVING COUNT(string)>=1;