2010-08-13 28 views
3

我想通过连续出现的列值对查询结果进行分组。比方说,我有一个表,其中列出了一个比赛的优胜者每年如下:MySQL组连续出现

year team_name 
2000 AAA 
2001 CCC 
2002 CCC 
2003 BBB 
2004 AAA 
2005 AAA 
2006 AAA 

我想查询其输出:

start_end total team_name 
2000   1  AAA 
2001-2002 2  CCC 
2003   1  BBB 
2004-2006 3  AAA 

我不是对过多担心格式为“start_end”,只要我有开始和结束或范围(例如,可以使用GROUP_CONCAT生成2004,2005,2006而不是2004-2006,这仍然可以)。

回答

3

只要您的表看起来像这样:

"id";"year";"team" 
"1";"2000";"AAA" 
"2";"2001";"CCC" 
"3";"2002";"CCC" 
"4";"2003";"BBB" 
"5";"2004";"AAA" 
"6";"2005";"AAA" 
"7";"2006";"AAA" 

这个查询应该做的伎俩:

SELECT a.year AS start 
    , MIN(c.year) AS end 
    , MIN(c.year)-a.year+1 AS total 
    , CONCAT_WS('-', a.year, IF(a.year = min(c.year), NULL, min(c.year))) as start_end 
    , a.team 
    FROM 
    (SELECT x.year, x.team, COUNT(*) id 
     FROM results x 
     JOIN results y 
      ON y.year <= x.year 
     GROUP BY x.id 
    ) AS a 
    LEFT JOIN 
    (SELECT x.year, x.team, COUNT(*) id 
     FROM results x 
     JOIN results y 
      ON y.year <= x.year 
     GROUP BY x.id 
    ) AS b ON a.id = b.id + 1 AND b.team = a.team 
    LEFT JOIN 
    (SELECT x.year, x.team, COUNT(*) id 
     FROM results x 
     JOIN results y 
      ON y.year <= x.year 
     GROUP BY x.id 
    ) AS c ON a.id <= c.id AND c.team = a.team 
    LEFT JOIN 
    (SELECT x.year, x.team, COUNT(*) id 
     FROM results x 
     JOIN results y 
      ON y.year <= x.year 
     GROUP BY x.id 
    ) AS d ON c.id = d.id - 1 AND d.team = c.team 
WHERE b.id IS NULL AND c.id IS NOT NULL AND d.id IS NULL 
GROUP BY start; 

顺便说一句,您可能会发现Common Queries Tree得心应手地解决这些问题(核对答案为“在序列中查找前一个值和下一个值“):p。

+0

感谢您的快速回复。为了让问题变得更容易,我对现实的某些方面进行了模糊处理:表中有一个额外的字段,称为“排名”,其值为“1”,“2”,“3”等,以便获得胜利者需要添加“WHERE排名= 1”的条件。如果我这样做了(我将这个条件添加到了每个选择的查询中),它给了我每年具有相同起始和结束值(即相应年份)的优胜者。此外,总数总是等于1. 我无法运行您的查询,因为这是因为在我的数据库中有10K +条目查询挂起。 – Max 2010-08-13 13:40:51

+0

你可以尝试创建一个只有获奖者记录的临时表,并在查询中使用它。这应该加快我想......即。运行CREATE TEMPORARY TABLE结果在运行发布在我的答案中的查询之前,选择id,year,team FROM your_table WHERE ranking = 1;顺便说一句,如果你仍然有很多赢家记录,你也可以在临时表中添加一个索引来加快速度。 – wimvds 2010-08-13 13:52:05

+0

创建临时表工作正常(我添加了IF NOT EXISTS,否则它会在进行多个测试时抱怨)。但是,现在您的查询在第一个子选择(我将别名重新命名为精确定位)失败,并显示“无法重新打开表格:'x'' – Max 2010-08-13 14:01:56