2010-11-22 2 views
0

Учитывая, что у меня есть таблица содержит данные пользователя, например:Как суммировать в PL/SQL

userID  calltime  result 
1   10:20   1 
1   11:00   2 
1   11:30   1 
2   9:30   1 
2   11:00   1 
3   10:00   1 
3   10:30   2 
3   11:00   1 
3   11:30   2 

Теперь я хочу резюмировать так:

userID  result1 result2 
1    2   1 
2    2   0 
3    2   2 
(total)  6   3 

для меня, суммируя пользовательские данные в порядке, но как я могу добавить общую строку в запрос? СОЮЗ не работает с этим.

Большое вам спасибо за это.

EDIT: это мой текущий запрос, конечно, он не работает:

PROCEDURE P_SUMMARIZE_CALL 
    (
    pStartDate IN DATE, 
    pEndDate IN DATE, 
    SummaryCur OUT MEGAGREEN_CUR  
) 
    IS 
    BEGIN 
    OPEN SUMMARYCUR FOR 
    SELECT USERID, TOTALCALLS,CONNECTEDCALLS,RATE,NOANSWER FROM 
    (((SELECT USERID, 
      count(CALLID) AS TOTALCALLS, 
      sum(CONNECTED) as CONNECTEDCALLS, 
      sum(CONNECTED)/count(CALLID)*100 || '%' AS RATE, 
      (count(CALLID) - sum(CONNECTED)) AS NOANSWER 
    FROM CALLLOGS 
    WHERE STARTTIME BETWEEN pStartDate AND pEndDate 
    group by USERID) c 
    FULL OUTER JOIN USERS u 
    ON c.USERID = u.ID) 

    UNION ALL 
    (SELECT NULL,count(CALLID) AS TOTALCALLS, 
      sum(CONNECTED) as CONNECTEDCALLS, 
      sum(CONNECTED)/count(CALLID)*100 || '%' AS RATE, 
      (count(CALLID) - sum(CONNECTED)) AS NOANSWER 
    FROM CALLLOGS 
    WHERE STARTTIME BETWEEN pStartDate AND pEndDate group by NULL)); 

    END; 
+0

Есть ли какая-то причина, по которой вы используете «ПОЛНУЮ ВНУТРЕННУЮ РАБОТУ»? Это, вероятно, делает больше работы, чем необходимо, так как кажется, что вы действительно хотите «ПРАВИЛЬНОЕ ВСТУПЛЕНИЕ», если я не ошибаюсь. И это вернет много полностью нулевых строк, так как вы используете c.USERID вместо u.ID –

+0

, что я хотел. Когда отображается в gridcontrol, значение null будет преобразовано в 0, если я не использую RIGHT OUTER JOIN, пользователь, который не имеет вызова, будет проигнорирован – Vimvq1987

ответ

5

Я предполагаю, что вы используете GROUP BY, чтобы сгенерировать текущий результат. (PS: Пожалуйста, опубликуйте свой текущий запрос, так как довольно сложно угадать, что вы делаете, чтобы получить этот результат).

Чтобы получить то, что вы хотите, используйте GROUP BY ROLLUP вместо GROUP BY.

UNION с этим не работает.

Да, на самом деле это тоже сработает. Но я бы предложил UNION ALL, а не UNION, поскольку ваш набор результатов, похоже, уже содержит только отдельные строки, поэтому нет смысла использовать дополнительное время вычисления для поиска повторяющихся строк для удаления.

+0

Спасибо. Я добавил запрос :) – Vimvq1987

+1

@ Vimvq1987: Измените 'group by USERID' на' group by rollup (USERID) '. –

1

Существует немного более быстрый способ сделать это ...

Предполагая, что вы можете получить только значение 1 или 2 на «результат» поле, это будет работать:

SELECT userid 
,  SUM(DECODE (result, 1, 1, 0)) as result1 
,  SUM(DECODE (result, 2, 1, 0)) as result2 
FROM x 
GROUP BY userid; 

Этот будет генерировать ожидаемый результат:

USERID RESULT1 RESULT2     
--------- --------- --------- 
1   2   1 
2   2   0 
3   2   2 

Если возможные значения на результате поля более чем на 1 или 2, вы можете добавить больше суммы-декодирование строк, или сделать вышеупомянутую процедуру PL/SQL.

+0

Altough DECODE более компактен, использование CASE является более гибким, а также более стандартным SQL. – gpeche

Смежные вопросы