在sql server中使用AVG在计算平均值时排除行

时间:2014-02-07 04:38:58

标签: sql sql-server-2008 database

我有这张桌子(工人)

ID      NAME                 ST     SALARY       DEP_ID
-----       -------------------- --  ---------  ---------
1       Arun                 MH      55000          22
2       Manish               MP      53000          11
3       Rahul                GJ      45000          22

我希望得到平均工资,而且平均而言我不想包括最低工资。

我写了这个查询

select AVG(w.salary)
from Worker w 
where w.salary  >(select MIN(w.salary) from Worker w)

可以在不使用子查询的情况下完成吗?

3 个答案:

答案 0 :(得分:2)

嗯,平均值只是总和/数,所以你可以这样做:

select (SUM(w.salary) - MIN(w.salary)) / (COUNT(w.salary) - 1)
from Worker w

修改:根据评论,如果有多个最低要求,并且您想要排除所有最小值,则上述解决方案不起作用。要在不使用子查询的情况下解决这个问题,我只能想到使用游标(这似乎有点过分)。尽管如此,以下符合要求:

DECLARE @min int = NULL
DECLARE @numMin int = 1
DECLARE @sum int = 0
DECLARE @current int
DECLARE @count int = 0

DECLARE db_cursor CURSOR FOR  
SELECT salary
FROM Worker

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @current

WHILE @@FETCH_STATUS = 0   
BEGIN
    IF @min IS NULL BEGIN
        SET @min = @current
    END
    ELSE IF @current < @min BEGIN
        SET @min = @current
        SET @numMin= 1
    END
    ELSE IF @current = @min BEGIN
        SET @numMin= @numMin + 1
    END

    SET @sum = @sum + @current  
    SET @count = @count + 1

    FETCH NEXT FROM db_cursor INTO @current   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

SELECT (@sum - @numMin * @min) / (@count - @numMin)

答案 1 :(得分:2)

我不知道这是否是SQL中的最佳做法

答案 2 :(得分:1)

如果没有子查询,我认为你不能真正做到这一点。问题是多个记录可能有最低工资。事实上,所有工资都可能是最低工资,平均甚至可能无法确定。

你可以这样做:

select AVG(w.salary)
from (select w.*, min(w.salary) over () as minsalary
      from Worker w 
     ) w
where w.salary > minsalary;

它仍有子查询,但不在where子句中。