我试图在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来产生这个但是如果汽车没有在一年之间制造,那么这就失败了。
答案 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
答案 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