你可能會採用case statement獲得獨家範圍的罪狀:
select case when [vendor experience] <= 6 then '0-6'
when [vendor experience] <= 12 then '0-12'
when [vendor experience] <= 18 then '0-18'
else 'more'
end [vendor_experience(months)],
count (*) [count]
from experiences
group by
case when [vendor experience] <= 6 then '0-6'
when [vendor experience] <= 12 then '0-12'
when [vendor experience] <= 18 then '0-18'
else 'more'
end
這會產生相同的結果和你(包括的範圍):
; with ranges as
(
select 6 as val, 0 as count_all
union all
select 12, 0
union all
select 18, 0
union all
select 0, 1
)
select case when ranges.count_all = 1
then 'more'
else '0-' + convert (varchar(10), ranges.val)
end [vendor_experience(months)],
sum (case when ranges.count_all = 1
or experiences.[vendor experience] <= ranges.val
then 1 end) [count]
from experiences
cross join ranges
group by ranges.val, ranges.count_all
count_all
設置爲1,以紀念開放結束範圍。
Sql Fiddle is here。
UPDATE:在解釋的嘗試。
第一部分開始with
並與右括號結束稱爲CTE。有時它被稱爲inline view
,因爲它可以在同一查詢中多次使用,並且在某些情況下是可更新的。此處用於準備範圍數據,並且適當命名爲ranges
。這個名稱在主查詢中使用。 Val
是範圍的最大值,count_all
如果範圍沒有上限(18+或更多,或者您希望稱之爲),則爲1。數據行通過union all進行組合。您可以僅在括號之間複製/粘貼部分,然後運行它以查看結果。
主體加入experiences
表使用cross join範圍。這會創建來自experiences
和ranges
的所有行的組合。對於d 11
行會有4行,在選擇列表
empname vendor experience val count_all
d 11 6 0
d 11 12 0
d 11 18 0
d 11 0 1
第一個case語句通過檢查count_all產生標題 - 如果它是一個,輸出more
,使用上限值else結構標題。第二種情況說明使用總和(1)進行計數。由於聚合函數忽略空值,如果未找到匹配,沒有其他值的情況下計算爲null,檢查count_all是否爲真(意味着來自經驗的該行計入此範圍內)就足夠了,或者如果小於或等於電流範圍的上限值。在上面的例子中,11不會被計入第一個範圍,但會被計入所有其他範圍。結果由val和count_all分組。爲了更好地瞭解它的工作原理,您可以在彙總之前刪除group by和sum()並查看數字。通過empname命令,val將幫助查看[count]的值如何根據每位員工的不同val而變化。
注意:我已經盡我所能用我目前的英語水平。如果您需要一個(或兩個,或者您需要的一樣多),請不要猶豫,要求澄清。
看看http://stackoverflow.com/questions/2483140/oracle-how-to-group-by-over-a-range - 它有點類似。 –
你真的想重複計算多個範圍內的人嗎? –