平均

2011-09-09 96 views
15

我稱之爲表請求和數據的模樣:平均

Req_ID R1 R2 R3 R4 R5 

R12673 2 5 3 7 10 
R34721 3 5 2 1 8 
R27835 1 3 8 5 6 

現在我想顯示R1,R2,R3,R4和R5的平均

所以我寫了一個查詢如:

Select Req_ID, Avg(R1+R2+R3+R4+R5) as Average 
from Request 
Group by Req_ID 

但我只是得到了R1,R2,R3,R4和R5的總和不是平均值嗎?我在哪裏做錯了。

+1

AVG適用於行,而不能在列。你期望答案是什麼? –

回答

14

如果數據被存儲爲INT,你可能想嘗試

Average = (R1 + R2 + R3 + R4 + R5)/5.0 
+1

R1,R2,R3,R4和R5都是真實數據類型 – Peter

+1

請記住,NULL值可能是一個問題。 Check @ martin-smith解決方案 – Jaider

+0

@Jaider那麼3.2和NULL的平均值是多少?除非另有說明,否則我會期望NULL的結果。 –

3

你可以簡單地做:

Select Req_ID, (avg(R1)+avg(R2)+avg(R3)+avg(R4)+avg(R5))/5 as Average 
from Request 
Group by Req_ID 

,對嗎?

我假設你可能具有相同REQ_ID多行並在這些情況下,您需要使用具有相同REQ_ID來計算所有列和行的平均對那些行

+0

@beetree Req_ID在表 – Peter

+0

@Aaron Bertrand中是唯一的我不知道這是OP想要什麼,但我沒有看到GROUP BY不能在那裏的語法原因... –

+0

哦,但是如果Req_ID在表格中是獨一無二的,爲什麼你有集團呢?沒有道理......? – beetree

21

你不提,如果列可以爲空。如果他們和你想的一樣的語義的AVG合計爲您提供可以做(2008)

SELECT *, 
     (SELECT AVG(c) 
     FROM (VALUES(R1), 
         (R2), 
         (R3), 
         (R4), 
         (R5)) T (c)) AS [Average] 
FROM Request 

2005年的版本是

SELECT *, 
     (SELECT AVG(c) 
     FROM (SELECT R1 
       UNION ALL 
       SELECT R2 
       UNION ALL 
       SELECT R3 
       UNION ALL 
       SELECT R4 
       UNION ALL 
       SELECT R5) T (c)) AS [Average] 
FROM Request 
+0

Martin Smith - 您能否在您提供的解決方案中解釋T(c)'''的意義? –

+0

@AlokShenoy T是派生表的別名,c是其單列的別名。 –

+0

啊!謝謝你的解釋。 –

4

在PostgreSQL,多一點乏味獲得的平均一行中的多個(2到8)列只定義了一組名爲average()的七個函數。將產生非空列的平均值。

然後就是

select *,(r1+r2+r3+r4+r5)/5.0,average(r1,r2,r3,r4,r5) from request; 
req_id | r1 | r2 | r3 | r4 | r5 |  ?column?  |  average 
--------+----+----+----+----+----+--------------------+-------------------- 
R12673 | 2 | 5 | 3 | 7 | 10 | 5.4000000000000000 | 5.4000000000000000 
R34721 | 3 | 5 | 2 | 1 | 8 | 3.8000000000000000 | 3.8000000000000000 
R27835 | 1 | 3 | 8 | 5 | 6 | 4.6000000000000000 | 4.6000000000000000 
(3 rows) 

update request set r4=NULL where req_id='R34721'; 
UPDATE 1 

select *,(r1+r2+r3+r4+r5)/5.0,average(r1,r2,r3,r4,r5) from request; 
req_id | r1 | r2 | r3 | r4 | r5 |  ?column?  |  average 
--------+----+----+----+----+----+--------------------+-------------------- 
R12673 | 2 | 5 | 3 | 7 | 10 | 5.4000000000000000 | 5.4000000000000000 
R34721 | 3 | 5 | 2 | | 8 |     | 4.5000000000000000 
R27835 | 1 | 3 | 8 | 5 | 6 | 4.6000000000000000 | 4.6000000000000000 
(3 rows) 

select *,(r3+r4+r5)/3.0,average(r3,r4,r5) from request; 
req_id | r1 | r2 | r3 | r4 | r5 |  ?column?  |  average 
--------+----+----+----+----+----+--------------------+-------------------- 
R12673 | 2 | 5 | 3 | 7 | 10 | 6.6666666666666667 | 6.6666666666666667 
R34721 | 3 | 5 | 2 | | 8 |     | 5.0000000000000000 
R27835 | 1 | 3 | 8 | 5 | 6 | 6.3333333333333333 | 6.3333333333333333 
(3 rows) 

像這樣:

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC, 
V3 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    IF V3 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V3; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC, 
V3 NUMERIC, 
V4 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    IF V3 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V3; END IF; 
    IF V4 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V4; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC, 
V3 NUMERIC, 
V4 NUMERIC, 
V5 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    IF V3 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V3; END IF; 
    IF V4 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V4; END IF; 
    IF V5 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V5; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC, 
V3 NUMERIC, 
V4 NUMERIC, 
V5 NUMERIC, 
V6 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    IF V3 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V3; END IF; 
    IF V4 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V4; END IF; 
    IF V5 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V5; END IF; 
    IF V6 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V6; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC, 
V3 NUMERIC, 
V4 NUMERIC, 
V5 NUMERIC, 
V6 NUMERIC, 
V7 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    IF V3 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V3; END IF; 
    IF V4 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V4; END IF; 
    IF V5 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V5; END IF; 
    IF V6 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V6; END IF; 
    IF V7 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V7; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 

CREATE OR REPLACE FUNCTION AVERAGE (
V1 NUMERIC, 
V2 NUMERIC, 
V3 NUMERIC, 
V4 NUMERIC, 
V5 NUMERIC, 
V6 NUMERIC, 
V7 NUMERIC, 
V8 NUMERIC) 
RETURNS NUMERIC 
AS $FUNCTION$ 
DECLARE 
    COUNT NUMERIC; 
    TOTAL NUMERIC; 
BEGIN 
    COUNT=0; 
    TOTAL=0; 
    IF V1 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V1; END IF; 
    IF V2 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V2; END IF; 
    IF V3 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V3; END IF; 
    IF V4 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V4; END IF; 
    IF V5 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V5; END IF; 
    IF V6 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V6; END IF; 
    IF V7 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V7; END IF; 
    IF V8 IS NOT NULL THEN COUNT=COUNT+1; TOTAL=TOTAL+V8; END IF; 
    RETURN TOTAL/COUNT; 
    EXCEPTION WHEN DIVISION_BY_ZERO THEN RETURN NULL; 
END 
$FUNCTION$ LANGUAGE PLPGSQL; 
+0

這可能是我會做的。存儲過程似乎比長查詢更緊湊,更易於閱讀。 – krishnab