2012-11-09 56 views
3

我有一個飼料應用程序,我試圖從連續分組結果。 我的表看起來像這樣:MySQL集團按連續行

postid | posttype | target | action  |  date   | title  | content 
     1 | userid | NULL | upgrade | 0000-01-00 00:00:00 | Upgraded 1 | exmple 
     1 | userid | NULL | upgrade | 0000-01-00 00:00:01 | Upgraded 2 | exmple 
     1 | userid | NULL | downgrade | 0000-01-00 00:00:02 | Downgraded | exmple 
     1 | userid | NULL | upgrade | 0000-01-00 00:00:03 | Upgraded | exmple 

我想結果是什麼要的是:

postid | posttype | target | action  |  date   | title  | content 
     1 | userid | NULL | upgrade | 0000-01-00 00:00:01 | Upgrade 1 | exmple,exmple 
     1 | userid | NULL | downgrade | 0000-01-00 00:00:02 | Downgraded | exmple 
     1 | userid | NULL | upgrade | 0000-01-00 00:00:03 | Upgraded | exmple 

所以你可以看到,因爲升級1個&升級2被送到連續地,這組在一起。 「動作」表是參考文獻,應該用於連續分組以及郵政編碼類型的郵政編碼&。

我環顧四周,但沒有看到任何與我的相似的東西。預先感謝您的幫助。

回答

3

這是另一個與MySQL變量一起工作的版本,不需要深入3層嵌套。第一個按postID和Date順序對記錄進行預先排序,並在每次發佈ID,類型和/或操作中的任何一個值發生變化時爲每個組分配一個順序編號。從那以後,它是一個簡單的團體......沒有比較記錄版本T到T2到T3 ......如果你想要4或5個標準......你將不得不嵌套更多條目嗎?或者只是增加2個@ SQL變量的對比測試......

你通話這是更有效的...

select 
     PreQuery.postID, 
     PreQuery.PostType, 
     PreQuery.Target, 
     PreQuery.Action, 
     PreQuery.Title, 
     min(PreQuery.Date) as FirstActionDate, 
     max(PreQuery.Date) as LastActionDate, 
     count(*) as ActionEntries, 
     group_concat(PreQuery.content) as Content 
    from 
     (select 
       t.*, 
       @lastSeq := if(t.action = @lastAction 
          AND t.postID = @lastPostID 
          AND t.postType = @lastPostType, @lastSeq, @lastSeq +1) as ActionSeq, 
       @lastAction := t.action, 
       @lastPostID := t.postID, 
       @lastPostType := t.PostType 
      from 
       t, 
       (select @lastAction := ' ', 
         @lastPostID := 0, 
         @lastPostType := ' ', 
         @lastSeq := 0) sqlVars 
      order by 
       t.postid, 
       t.date) PreQuery 
    group by 
     PreQuery.postID, 
     PreQuery.ActionSeq, 
     PreQuery.PostType, 
     PreQuery.Action  

這裏是我的link to SQLFiddle sample

爲標題,你可能需要調整行.. 。

group_concat(distinct PreQuery.Title)as Title,

至少這會給DISTINCT標題concatinated ...更困難得到讓我們沒有嵌套整個查詢一個更多的級別,通過最大查詢日期和其他元素獲得與所有標準的最大日期關聯的一個標題。

+0

你的代碼似乎確實快得多!你會推薦什麼來獲取最後一個標題而不創建另一個子查詢:(SELECT t2.title FROM t2 WHERE t2.id = MAX(t.id))? – Corey

+0

@Corey,修改後的答案... – DRapp

+0

感謝您的回覆 - 非常感謝! – Corey

1

表中沒有主鍵,所以對於我的示例,我使用date。您應該創建一個自動增量值,並在我的示例中使用該值,而不是date

這是一個溶液(view on SQL Fiddle):

SELECT 
    postid, 
    posttype, 
    target, 
    action, 
    COALESCE((
    SELECT date 
    FROM t t2 
    WHERE t2.postid = t.postid 
    AND t2.posttype = t.posttype 
    AND t2.action = t.action 
    AND t2.date > t.date 
    AND NOT EXISTS (
     SELECT TRUE 
     FROM t t3 
     WHERE t3.date > t.date 
     AND t3.date < t2.date 
     AND (t3.postid != t.postid OR t3.posttype != t.posttype OR t3.action != t.action) 
    ) 
), t.date) AS group_criterion, 
    MAX(title), 
    GROUP_CONCAT(content) 
FROM t 
GROUP BY 1,2,3,4,5 
ORDER BY group_criterion 

它基本上讀取:

對於每一行創建一組標準,並通過它的端基英寸
該標準是當前之後的行的最高date,與當前版本具有相同的postid,posttype和action,但它們之間可能不存在一行不同的postid,posttype或action。
換句話說,組標準是一組連續條目中的最高發生日期。

如果你使用正確的索引,它不應該非常慢,但如果你有很多行,你應該考慮緩存這些信息。

+0

對不起,我只發佈了我認爲與查詢相關的字段。 全表:ID,組,帖子ID,posttype,行動,目標日期,\t標題,內容,鏈接,發表 (ID是主鍵) – Corey

+1

你說的是分組連續的條目,你認爲自動增量主鍵與查詢無關?非常可聽。 ;) – AndreKR

+0

你說得對,哈哈,我不知道我在想什麼,甚至當我自己嘗試時,我正在嘗試使用ID。我需要一杯咖啡!我可能很快就會有另一個問題。謝謝! – Corey