2014-10-16 119 views
0

我正在使用Oracle SQL,我需要查询帮助。数值范围的平均值

我有如下表:

Age (int) 
Salary (int) 

输入例如:

Age | Slary 
18 | 5000 
18 | 10000 
20 | 11000 
24 | 9000 
21 | 6000 
21 | 7000 
22 | 6000 
28 | 22000 

我需要通过年龄的范围来计算平均工资。每两年都是一场风暴。输出示例:

Age Range | Average Salary 
18 - 20 | 8666.666 
19 - 21 | 8000 
20 - 22 | 7500 
21 - 23 | 6333.33 
22 - 24 | 7500 
23 - 25 | 7500 
24 - 26 | 7500 
26 - 28 | 22000 
27 - 29 | 22000 
28 - 30 | 22000 

顺便说一句,这是可能的分裂“年龄范围”一栏分成两个不同的列:“最小年龄”和“最大年龄”,如果它更容易实现。

任何建议如何做到这一点?

+0

请提供一些输入.. – SonalPM 2014-10-16 11:53:42

+0

是否打算3年范围重叠? – TheConstructor 2014-10-16 11:54:39

+0

@TheConstructor:我不知道我完全理解你的问题。年龄栏中的值未知。例如,可能没有34-36的年龄值,因此此范围将不会包含在“年龄范围”输出列中。 – Omri 2014-10-16 12:03:26

回答

0

我认为这可能是你想要的东西(它在改编自通过迪帕克·帕瓦尔答案的方法的一部分,但调整到Oracle的语法)。我注意到23-25组的值在我的查询中为9000,但样本数据为7500,但我认为样本数据不正确,9000确实是正确的值(对于24-26也是如此)。

Oracle不是我的选择数据库,我相信通过更熟悉Oracle开发的人员可以改进查询。

SQL Fiddle

的Oracle 11g R2架构设置

CREATE TABLE t ("Age" int, "Salary" int); 

INSERT ALL 
    INTO t ("Age", "Salary") VALUES (18, 5000) 
    INTO t ("Age", "Salary") VALUES (18, 10000) 
    INTO t ("Age", "Salary") VALUES (20, 11000) 
    INTO t ("Age", "Salary") VALUES (24, 9000) 
    INTO t ("Age", "Salary") VALUES (21, 6000) 
    INTO t ("Age", "Salary") VALUES (21, 7000) 
    INTO t ("Age", "Salary") VALUES (22, 6000) 
    INTO t ("Age", "Salary") VALUES (28, 22000) 
SELECT * FROM dual; 

查询1

WITH counter 
AS ( 
    SELECT 
    LEVEL-1 low, 
    LEVEL+1 high 
    FROM DUAL 
    WHERE (LEVEL-1) >= (SELECT MIN("Age") FROM t) 
    CONNECT BY LEVEL-1 <= (SELECT MAX("Age") FROM t) 
) 

SELECT 
    (low || ' - ' || high) "Age Range", 
    Avg("Salary") "Average Salary" 
FROM t 
RIGHT OUTER JOIN counter c ON t."Age" >= c.low AND t."Age" <= c.high 
GROUP BY low, high 
ORDER BY 1 

Results

| AGE RANGE | AVERAGE SALARY | 
|-----------|-------------------| 
| 18 - 20 | 8666.666666666666 | 
| 19 - 21 |    8000 | 
| 20 - 22 |    7500 | 
| 21 - 23 | 6333.333333333333 | 
| 22 - 24 |    7500 | 
| 23 - 25 |    9000 | 
| 24 - 26 |    9000 | 
| 25 - 27 |   (null) | 
| 26 - 28 |    22000 | 
| 27 - 29 |    22000 | 
| 28 - 30 |    22000 | 
+0

谢谢!这就是我期待的。 – Omri 2014-10-17 13:03:28

1

这可能有助于(MSSQL脚本):

SELECT Cast(LowerLimit AS VARCHAR) + ' - ' 
     + Cast(UpperLimit AS VARCHAR) AgeRange, 
     Avg(salary)     averagesalary 
FROM MyTable t1 
     RIGHT OUTER JOIN (SELECT Age  AS LowerLimit, 
           Age + 2 AS UpperLimit 
         FROM MyTable) AS t2 
        ON t1.Age >= t2.LowerLimit 
         AND t1.Age <= t2.UpperLimit 
GROUP BY LowerLimit,UpperLimit