我希望在我的选择中获得每个赛季的前5行。我有4个赛季:SUM, SPR, AUT, WIN
。
所以总共应该有20行。
我的选择看起来像这样:
select *
from (
select year, season, ROUND(avg(temperature),1) as avgTemp
from temperature join month on temperature.MONTH = month.MONTH
group by (season, year)
order by season, avgTemp asc
) where rownum <= 5;
它仅适用于一个季节。输出是:
1993 AUT 8,7
2007 AUT 9,9
1996 AUT 10
1998 AUT 10
2008 AUT 10,5
但看起来应该是这样的:
1996 SPR 9.6
1991 SPR 10.3
2006 SPR 10.3
2004 SPR 10.6
1995 SPR 10.6
1996 SUM 18.9
1993 SUM 19.1
2007 SUM 19.5
1998 SUM 19.5
2000 SUM 19.6
1993 AUT 8.7
2007 AUT 9.9
1998 AUT 10.0
1996 AUT 10.0
2008 AUT 10.5
1996 WIN .3
1991 WIN 1.2
2003 WIN 1.6
2006 WIN 1.9
2005 WIN 2.0
您知道如何改善选择或者您有其他建议吗?提前谢谢!
答案 0 :(得分:2)
您需要分三步完成:
SQL应该看起来像这样(未经测试):
select year, season, avg_temp
from (
select year, season, avg_temp,
row_number() over(partition by season order by avg_temp) rn
from (
select year, season, ROUND(avg(temperature),1) as avg_temp
from temperature
join month on temperature.MONTH = month.MONTH
group by season, year
)
)
where rn <= 5;
<强>更新强>
对于季节特别订购,请添加:
order by case season
when 'SPR' then 1
when 'SUM' then 2
when 'AUT' then 3
when 'WIN' then 4
end, avg_temp;
答案 1 :(得分:1)
WITH cteAverageTempByYearBySeason AS (
SELECT
year
,season
,ROUND(AVG(temperature),1) as AvgTemp
FROM
Temperature t
INNER JOIN Month m
On t.MONTH = m.MONTH
GROUP BY
year
,season
)
, cteRowNumber AS (
SELECT
*
,ROW_NUMBER() OVER (PARTITION BY season ORDER BY AvgTemp ASC) as RowNumber
FROM
cteAverageTempByYearBySeason
)
SELECT *
FROM
cteRowNumber
WHERE
RowNumber <= 5
这是一个例子。我将派生表分解为公用表表达式,以使逻辑更加明显。您需要创建一个PARTITIONED ROW_NUMBER()
,而不仅仅是使用特殊的rownumber
。后者只返回与TOP/LIMIT 5
相同的位置,因为前者允许您每季识别5行。
编辑为您的订单添加了一个巧妙的技巧,因此您不必编写案例表达式。这个使用你的月号,我假设它是MONTH
列。
WITH cteAverageTempByYearBySeason AS (
SELECT
year
,season
,ROUND(AVG(temperature),1) as AvgTemp
,MAX(m.MONTH) as SeasonOrderBy
FROM
Temperature t
INNER JOIN Month m
On t.MONTH = m.MONTH
GROUP BY
year
,season
)
, cteRowNumber AS (
SELECT
*
,ROW_NUMBER() OVER (PARTITION BY season ORDER BY AvgTemp ASC) as RowNumber
FROM
cteAverageTempByYearBySeason
)
SELECT
year
,season
,AVG
FROM
cteRowNumber
WHERE
RowNumber <= 5
ORDER BY
SeasonOrderBy
,AvgTemp
,Year
答案 2 :(得分:0)
您需要使用row_number
为每个分组获取5行:
select
year,
season,
round(avg(temperature), 1) as avgTemp
from (
select *,
row_number() over(partition by season, year order by season, avgTemp) as rn
from temperature t
join month m
on m.MONTH = t.MONTH
) a
where
a.rn <= 1