2

我正在尝试汇总 sql 中的数据,并且很难找到对数据进行分组的方法。

我有一张叫汽车的桌子

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

4 回答 4

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

小提琴演示

于 2012-10-26T10:04:55.880 回答
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 小提琴示例

编辑

如果我正确解释了要求,请使用 RICHARD THE KIWI 的回答。它比我的好多了!

小提琴改进的解决方案

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
于 2012-10-26T10:34:40.167 回答
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

于 2012-10-26T10:59:40.603 回答
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
于 2012-10-26T12:13:56.357 回答