2014-01-31 20 views
0
user_id | username | salary | 
+---------+----------+------+ 
|  1 | John  | 4000 | 
|  2 | Paul  | 0900 | 
|  3 | Adam  | 0589 | 
|  4 | Ben  | 2154 | 
|  5 | Charles | 2489 | 
|  6 | Dean  | 2500 | 
|  7 | Edward | 2900 | 
|  8 | Fred  | 2800 | 
|  9 | George | 4100 | 
|  10 | Hugo  | 5200 | 

我需要這樣Oracle組由工資範圍(0-999,1000-1999,2000-2999,...)

range  count 
-------------------- 
0-999  2 

1000-1999 0 

2000-2999 5 

3000-3999 0 

4000-4999 2 

5000-5999 1 
+0

你的問題是什麼?我假設你正在嘗試創建一個查詢來做到這一點 - 你到目前爲止已經嘗試過了什麼,以及在哪裏遇到問題? – Krease

+2

您的薪水欄中有0。是一個數字還是一個字符? – Ben

回答

1

的Oracle 11g R2架構設置輸出:

create table test_table as 
select 1 user_id, 'John' username , 4000 salary from dual union all 
select 2 , 'Paul'  , 0900 from dual union all 
select 3 , 'Adam'  , 0589 from dual union all 
select 4 , 'Ben'  , 2154 from dual union all 
select 5 , 'Charles' , 2489 from dual union all 
select 6 , 'Dean'  , 2500 from dual union all 
select 7 , 'Edward' , 2900 from dual union all 
select 8 , 'Fred'  , 2800 from dual union all 
select 9 , 'George' , 4100 from dual union all 
select 10 , 'Hugo'  , 5200 from dual 

查詢1

with range_tab(f,t) as (select (level - 1)*1000 , (level - 1)*1000 + 999 
    from dual 
connect by (level - 1)*1000 <= (select max(salary) from test_table)) 
select f ||'-'|| t as range, count(user_id) 
    from test_table 
    right outer join range_tab on (salary between f and t) 
group by f, t 
order by 1 

[結果] [2]

|  RANGE | COUNT(USER_ID) | 
|-----------|----------------| 
|  0-999 |    2 | 
| 1000-1999 |    0 | 
| 2000-2999 |    5 | 
| 3000-3999 |    0 | 
| 4000-4999 |    2 | 
| 5000-5999 |    1 | 
1

下面是一個嘗試:

with w as 
(
    select 1000 * (level - 1) low, 1000 * level high from dual 
    connect by level <= 10 
) 
select w.low, w.high, sum(decode(t.user_id, null, 0, 1)) nb 
from w, test_epn t 
where w.low <= t.salary (+) 
    and w.high > t.salary (+) 
group by w.low, w.high 
order by w.low 
; 

這給出:

1 0 1000 2 
2 1000 2000 0 
3 2000 3000 5 
4 3000 4000 0 
5 4000 5000 2 
6 5000 6000 1 
7 6000 7000 0 
8 7000 8000 0 
9 8000 9000 0 
10 9000 10000 0 
1
SQL> col range format a30 
SQL> with t as (
    2 select 'John' name, 4000 sal from dual union all 
    3 select 'Paul' name, 900 from dual union all 
    4 select 'Adam' name, 589 from dual union all 
    5 select 'Ben' name, 2154 from dual union all 
    6 select 'Charles' name, 2489 from dual union all 
    7 select 'Dean' name, 2500 from dual union all 
    8 select 'Edward' name, 2900 from dual union all 
    9 select 'Fred' name, 2800 from dual union all 
10 select 'George' name, 4100 from dual union all 
11 select 'Hugo' name, 5200 from dual 
12 ) 
13 select to_char(pvtid*1000)||'-'||to_char(pvtid*1000+999) range, count(t.sal) 
14 from t 
15 , 
16 (
17 select rownum-1 pvtid 
18 from dual connect by level <= (select floor(max(sal)/1000) from t)+1 
19 ) piv 
20 where piv.pvtid = floor(t.sal(+)/1000) 
21 group by piv.pvtid 
22 order by 1 
23/

RANGE       COUNT(T.SAL)          
------------------------------ ------------          
0-999          2          
1000-1999         0          
2000-2999         5          
3000-3999         0          
4000-4999         2          
5000-5999         1 
1

在固定的時間間隔就可以的情況下也使用Oracle WIDTH_BUCKE T功能。

select count(*), 
(WIDTH_BUCKET(salary, 0, 10000,10)-1)*1000 ||'-'||to_char(WIDTH_BUCKET(salary, 0, 10000,10)*1000-1) as salary_range 
from table1 
group by WIDTH_BUCKET(salary, 0, 10000,10) 
order by salary_range; 

| COUNT(*) | SALARY_RANGE | 
|----------|--------------| 
|  2 |  0-999 | 
|  5 | 2000-2999 | 
|  2 | 4000-4999 | 
|  1 | 5000-5999 | 

缺點是:它不包括空桶,但也許這滿足您的需求。