2012-10-26 89 views
2

我想sumarise中的数据,并且很难找到用于分组数据的方法。将数据总结为年份范围

我有一个表,名为汽车

CarID CarMake CarModel CarYear 
1  Ford  Mondeo 2000 
2  Ford  Mondeo 2002 
3  Ford  Mondeo 2003 
4  Ford  Mondeo 2005 

我希望能集团这一数据显示为

CarMake CarModel CarYearRange 
Ford  Mondeo 2000-2003 
Ford  Mondeo 2005-2005 

我一直在使用的最小和最大生产这种然而,这失败如果尝试例如,这辆车不是在一年之间制造的。

+3

您如何确定年份范围? – RichardTheKiwi

回答

2
select carmake, carmodel, 
case when caryear >= 2000 and caryear <=2003 then '2000-2003' 
    when caryear >= 2005 and caryear <=2005 then '2005-2005' 
end t 
from car 
group by carmake, carmodel , t 

fiddle demo

+2

你可以通过问题标签检查这是否适用于SQL-SERVER? – RichardTheKiwi

2

我假定(也许brashly),你的样本数据中包含一个错误,该范围应该是2000年,2002- 2003年,和2005年因为有2001年或没有模型2004年如果我是正确的,那么这将工作:

WITH CTE AS 
( SELECT Cars.CarMake, 
      Cars.CarModel, 
      [FirstYear] = Cars.CarYear, 
      [LastYear] = Cars.CarYear, 
      [Recursion] = 1 
    FROM Cars 
    UNION ALL 
    SELECT CTE.CarMake, 
      CTE.CarModel, 
      CTE.[FirstYear], 
      [LastYear] = Cars.CarYear, 
      [Recursion] = [Recursion] + 1 
    FROM CTE 
      INNER JOIN Cars 
       ON CTE.CarMake = Cars.CarMake 
       AND CTE.CarModel = Cars.CarModel 
       AND CTE.[LastYear] = Cars.CarYear - 1 
), MaxCTE AS 
( SELECT CarMake, 
      CarModel, 
      FirstYear, 
      LastYear, 
      Recursion, 
      [MaxRecursion] = MAX(Recursion) OVER(PARTITION BY CarMake, CarModel, FirstYear) 
    FROM CTE 
) 
SELECT MaxCTE.CarMake, 
     MaxCTE.CarModel, 
     [CarYearRange] = CAST(FirstYear AS VARCHAR(4)) + ' - ' + CAST(LastYear AS VARCHAR(4)) 
FROM MaxCTE 
WHERE Recursion = MaxRecursion 
AND  NOT EXISTS 
     ( SELECT 1 
      FROM MaxCTE ex 
      WHERE MaxCTE.CarMake = ex.CarMake 
      AND  MaxCTE.CarModel = ex.CarModel 
      AND  MaxCTE.FirstYear > ex.FirstYear 
      AND  MaxCTE.LastYear = ex.LastYear 
     ) 

SQL Fiddle Example

编辑

如果我已经正确地解释了要求,使用RICHARD的KIWI的答案。它比矿井好得多!

Fiddle for the improved solution

SELECT CarMake, 
     CarModel, 
     [StartYear] = MIN(CarYear), 
     [EndYear] = MAX(CarYear) 
FROM ( SELECT *, 
        [Offset] = CarYear - ROW_NUMBER() OVER (PARTITION BY CarMake, CarModel ORDER BY CarYear) 
      FROM Cars 
     ) x 
GROUP BY CarMake, CarModel, Offset 
ORDER BY CarMake, CarModel, StartYear 
2

在SQL Server中,可以使用类似于这样:

select distinct carmake, 
    carmodel, 
    case 
    when caryear >= 2000 and caryear <= 2003 then '2000-2003' 
    when caryear >= 2005 and caryear <= 2005 then '2005-2005' 
    end CarYearRange 
from yourtable 

SQL Fiddle with Demo

1

从您的需求GarethD的解释得到暗示,这里是我的查询来获得所需的结果。我强烈建议将范围显示为2个不同的列,并让前端代码合并它们以供显示(如果需要)。

select carmake, 
     carmodel, 
     min(caryear) startyear, 
     max(caryear) endyear 
from (
    select *, 
     offset= caryear-row_number() over (partition by carmake, carmodel 
              order by caryear) 
    from cars 
) x 
group by carmake, carmodel, offset 
order by carmake, carmodel, startyear 
+0

+1比我的解决方案好得多。我曾经多次看到过的一个诀窍,并且多次被遗忘。希望这次能回忆我的记忆! – GarethD