據我所知,您的目標是找到任何Application
其最近五次運行都是FAILED
狀態。
PL/SQL
不是實現這個目標所必需的;它可以用正常SQL
來實現。
如果需要編譯爲過程,則可以根據需要將SQL合併到過程塊中。
下面是一個例子,但應該指出有很多方法可以獲得這種數據。
首先,創建表:
CREATE TABLE APPLICATION_RUN (APPLICATION_NAME VARCHAR2(64), EVENT_DATE DATE, EVENT_STATUS VARCHAR2(64));
然後加載數據。
本例中包含了一些額外的數據,因爲您的文章沒有任何5個最近執行的例子都是失敗的。
該數據包括Application 3
的最近5次故障以及Application 1
的5次以上的故障。還有一個Application 4
,它只有一次失敗(還沒有運行過5次)。
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('10-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('11-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('12-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('13-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('14-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('15-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('16-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('17-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('18-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('19-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('20-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('21-MAR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('22-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('23-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 1',TO_DATE('25-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('24-MAR-17','DD-MON-YY'),'SUCCEEDED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('20-APR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('21-APR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('22-APR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('23-APR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('24-APR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('25-APR-17','DD-MON-YY'),'FAILED');
INSERT INTO APPLICATION_RUN VALUES ('Application 4',TO_DATE('25-APR-17','DD-MON-YY'),'FAILED');
然後查詢。
這個例子有三個步驟: 首先,根據應用程序的運行日期排序,最近的排在第一位。
然後,扔掉除最近五個之外的所有東西,然後扔掉總計少於5次的任何東西。
最後檢查是否所有這五個都是FAILED
。此示例查詢使用命名的子因子查詢進行佈局,以突出顯示這些目標。
WITH FIVE_MOST_RECENT_RUN AS (
SELECT
APPLICATION_NAME,
EVENT_DATE,
EVENT_STATUS
FROM
(SELECT
APPLICATION_RUN.APPLICATION_NAME,
APPLICATION_RUN.EVENT_DATE,
APPLICATION_RUN.EVENT_STATUS,
DENSE_RANK()
OVER (
PARTITION BY APPLICATION_RUN.APPLICATION_NAME
ORDER BY EVENT_DATE DESC) AS EVENT_RANK
FROM APPLICATION_RUN) RANKED_APPLICATION_RUN
WHERE RANKED_APPLICATION_RUN.EVENT_RANK < 6),
RUN_STATUS_VARIATION AS (
SELECT
FIVE_MOST_RECENT_RUN.APPLICATION_NAME,
COUNT(DISTINCT FIVE_MOST_RECENT_RUN.EVENT_STATUS) AS STATUS_VARIATIONS,
MAX(FIVE_MOST_RECENT_RUN.EVENT_STATUS)
KEEP
(DENSE_RANK FIRST
ORDER BY FIVE_MOST_RECENT_RUN.EVENT_DATE DESC) AS MOST_RECENT_STATUS
FROM FIVE_MOST_RECENT_RUN
GROUP BY FIVE_MOST_RECENT_RUN.APPLICATION_NAME
HAVING COUNT(*) > 4)
SELECT RUN_STATUS_VARIATION.APPLICATION_NAME
FROM RUN_STATUS_VARIATION
WHERE RUN_STATUS_VARIATION.STATUS_VARIATIONS = 1
AND RUN_STATUS_VARIATION.MOST_RECENT_STATUS = 'FAILED';
然後對其進行測試:
APPLICATION_NAME
Application 3
如果你添加一個新的,SUCCEEDED
運行的Application 3
更近的比別人,不再查詢返回Application 3
。
INSERT INTO APPLICATION_RUN VALUES ('Application 3',TO_DATE('26-APR-17','DD-MON-YY'),'SUCCEEDED');
,並再次運行:
no rows selected
你嘗試過這麼遠嗎? SO不適用於像「如何做到這一點」這樣的問題,所以你應該先做一些搜索,然後試一下,如果你被困在一些代碼中,問一個問題 – Aleksej
什麼是期望的輸出? –
我必須找到具有五個重要故障狀態的應用程序。 – MileP