将数据汇总到年份范围

时间:2012-10-26 09:23:10

标签: sql sql-server-2005

我试图在sql中提取数据,但我很难找到一种分组数据的方法。

我有一张名为cars的表

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

我尝试过使用min和max来产生这个但是如果汽车没有在一年之间制造,那么这就失败了。

4 个答案:

答案 0 :(得分: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

for fiddle demo

答案 1 :(得分:2)

我假设(也许是莽撞地)你的样本数据包含错误,并且范围应该是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 :(得分: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

答案 3 :(得分: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