有查询的Oracle查询

时间:2013-12-05 15:06:24

标签: oracle group-by having

我需要对v$session_wait查找事件进行查询,我需要获取具有特定最大值的事件:例如:

db file scattered read > 20 
db file sequential read > 25 
buffer busy   waits > 30 
SQL*Net message from dblink > 20 
log file sync > 10

我有这个问题:

SELECT COUNT(*), event
FROM v$session_wait
WHERE event NOT IN ('pipe get','PL/SQL lock timer','SQL*Net more data from
client','queue messages','SQL*Net message from client','pmon timer','rdbms ipc 
message','SQL*Net message to client','smon timer','wakeup time manager','virtual 
circuit status','wait for unread message on broadcast channel','jobq slave wait')
AND event NOT LIKE 'Streams%AQ%'
GROUP BY event
HAVING COUNT('db file scattered read')  >= 4 
OR COUNT('db file sequential read')     >= 4 
OR COUNT('buffer busy waits')           >= 7 
OR COUNT('latch free%')                 >= 1 
OR COUNT('library cache%')              >= 8 
OR COUNT('enqueue')                     >= 8 
OR COUNT('read by other session')       >= 8 
OR COUNT('log file sync')               >= 2 
OR COUNT('SQL*Net message from dblink') >= 2 
;

但结果不是我想要的。

我需要将每个事件和结果分组为上面的最大值。

任何帮助?

1 个答案:

答案 0 :(得分:1)

在这种情况下,HAVING条款是错误的。你可以像这样重写:

SELECT event,cnt 
FROM (
    SELECT COUNT(*) as cnt, event
    FROM v$session_wait
    WHERE event NOT IN (
        'pipe get', 'PL/SQL lock timer', 'SQL*Net more data from client', 
        'queue messages', 'SQL*Net message from client', 'pmon timer', 
        'rdbms ipc message', 'SQL*Net message to client', 'smon timer', 
        'wakeup time manager', 'virtual  circuit status', 
        'wait for unread message on broadcast channel', 'jobq slave wait'
        )
      AND event NOT LIKE 'Streams%AQ%'
    GROUP BY event
) a
WHERE (CASE WHEN event = 'db file scattered read' AND cnt >= 4 THEN 1
        WHEN event = 'db file sequential read' AND cnt >= 4 THEN 1
        WHEN event = 'buffer busy waits' AND cnt >= 7 THEN 1
        WHEN event = 'latch free%' AND cnt >= 1 THEN 1
        WHEN event = 'library cache%' AND cnt >= 8 THEN 1
        WHEN event = 'enqueue' AND cnt >= 8 THEN 1
        WHEN event = 'read by other session' AND cnt >= 8 THEN 1
        WHEN event = 'log file sync' AND cnt >= 2 THEN 1
        WHEN event = 'SQL*Net message from dblink' AND cnt >= 2 THEN 1
        ELSE 0 END) = 1

但是如果你想在内部查询中使用MAX作为COUNT的行,你可以这样做:

SELECT event,cnt 
FROM (
    SELECT COUNT(*) as cnt, event
    FROM v$session_wait
    WHERE event NOT IN (
        'pipe get', 'PL/SQL lock timer', 'SQL*Net more data from client', 
        'queue messages', 'SQL*Net message from client', 'pmon timer', 
        'rdbms ipc message', 'SQL*Net message to client', 'smon timer', 
        'wakeup time manager', 'virtual  circuit status', 
        'wait for unread message on broadcast channel', 'jobq slave wait'
        )
    AND event NOT LIKE 'Streams%AQ%'
    GROUP BY event
    ORDER BY COUNT(*) DESC
) a
WHERE ROWNUM = 1