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 を使用してこれを生成しようとしましたが、例のように車が 1 年以内に製造されていない場合、これは失敗します。

4

4 に答える 4

2

サンプルデータにエラーが含まれており、2001または2004のモデルがないため、範囲は2000、2002-2003、および2005であると想定しました。私が正しければ、これは機能します。

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フィドルの例

編集

要件を正しく解釈した場合は、リチャード・ザ・キウイの回答を使用してください。それは私のものよりもはるかに優れています!

改善されたソリューションのフィドル

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 に答える
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 に答える
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 に答える