2015-02-10 40 views
0

我有一個具有運行狀態的流程引擎1,2,3,4,5,6的表。當其中一個引擎停機時,記錄將從表中刪除。使用case語句,我可以顯示停機的第一個引擎,但是如果有兩個或更多個引擎停機,我該如何去顯示引擎。對於例如如何使這個查詢顯示PE 2 IS DOWN,並且如果兩個引擎都關閉,PE 4將DOWN。現在它只顯示列表中第一個關閉的引擎。SQL CASE對無數據的聲明

SELECT CASE 
WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 1) = 0 THEN 'PE 1 IS DOWN' 
WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 2) = 0 THEN 'PE 2 IS DOWN' 
WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 3) = 0 THEN 'PE 3 IS DOWN' 
WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 4) = 0 THEN 'PE 4 IS DOWN' 
WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 5) = 0 THEN 'PE 5 IS DOWN' 
WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 6) = 0 THEN 'PE 6 IS DOWN' 
ELSE 'ALL PROCESS ENGINES ARE UP AND RUNNING' 
END "STATUS" 
from dual; 
+0

你正在使用什麼數據庫?根據數據庫可以製作更好的目標腳本。 – ps2goat 2015-02-10 22:16:45

+0

@ ps2goat'dual'通常是oracle – 2015-02-10 22:20:01

+0

我使用的是ORACLE 11.2.0 – ram81012 2015-02-10 22:20:38

回答

3

相反情況下,使用union all了兩種不同的情況,所有的好與一些沒有運行。子查詢分解以減少重複代碼。

with engines as (select level as engine_number 
    from dual 
    connect by level <= 6) 
, down_engines as (select engine_number 
    from engines 
    where engine_number not in (select pe_id from cwvminfo)) 
select to_char(engine_number) || ' IS DOWN' 
from down_engines 
union all 
select 'all engines are running' 
from dual 
where not exists (select null from down_engines) 
+0

非常感謝你香農!這就像一個魅力,正是我所需要的!謝謝! – ram81012 2015-02-13 18:26:01

0

您可以使用多個CASE表達式爲每個返回狀態:

WITH cte AS (
SELECT CASE WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 1) = 0 THEN 'PE 1 IS DOWN' END AS PE_1 
     ,CASE WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 2) = 0 THEN 'PE 2 IS DOWN' END AS PE_2 
     ,CASE WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 3) = 0 THEN 'PE 3 IS DOWN' END AS PE_3 
     ,CASE WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 4) = 0 THEN 'PE 4 IS DOWN' END AS PE_4 
     ,CASE WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 5) = 0 THEN 'PE 5 IS DOWN' END AS PE_5 
     ,CASE WHEN (SELECT COUNT(PE_ID) FROM CWVMINFO WHERE PE_ID = 6) = 0 THEN 'PE 6 IS DOWN' END AS PE_6 
     from dual) 
SELECT *,CASE WHEN COALESCE(PE_1,PE_2,PE_3,PE_4,PE_5,PE_6) IS NULL THEN 'ALL PROCESS ENGINES ARE UP AND RUNNING' END "STATUS" 
FROM cte 
+2

我不認爲你的替代查詢會起作用......不會有任何具有'PE_ID'特定值的行。 – 2015-02-10 22:40:17

+0

@DavidFaber哈,好點,刪除了。 – 2015-02-10 22:42:21

+0

僅供參考...您需要在CTE中使用「雙重」。 – 2015-02-10 22:46:33

0

我會寫一個存儲過程,如果條件爲每個在這裏的情況。

0

您可以嘗試以下操作。這有點笨拙,但我認爲它可能工作。

WITH p1 AS (
    SELECT LEVEL AS pe_id 
     FROM dual 
    CONNECT BY LEVEL <= 6 
) 
SELECT DISTINCT CASE WHEN all_ind = 0 THEN 'ALL PROCESS ENGINES ARE UP AND RUNNING' 
    WHEN process_cnt = 0 THEN 'PE ' || pe_id || ' IS DOWN' END AS status 
    FROM (
    SELECT pe_id, process_cnt 
     , SUM(DECODE(process_cnt, 0, 1, 0)) OVER () AS all_ind 
     FROM (
     SELECT p1.pe_id, COUNT(c1.pe_id) AS process_cnt 
      FROM p1 LEFT JOIN cwvminfo c1 
      ON p1.pe_id = c1.pe_id 
     GROUP BY p1.pe_id 
    ) 
) 

Please see SQL Fiddle here.

+0

非常感謝大衛!由於某種原因,查詢會在結果集中抽取一個空值,但我只能處理空值並獲取其餘數據。 – ram81012 2015-02-13 18:27:47

+0

它會拉出一個'NULL'。我會做些什麼來濾除它,但我不想對子查詢過深。 – 2015-02-13 20:14:07

1

我想這個使用單個查詢和有條件的聚集改寫:

select coalesce(case when sum(case when pe_id = 1 then 1 else 0 end) = 0 
        then 'PE 1 IS DOWN; ' 
       end) || 
       (case when sum(case when pe_id = 1 then 2 else 0 end) = 0 
        then 'PE 2 IS DOWN; ' 
       end) || 
       (case when sum(case when pe_id = 1 then 3 else 0 end) = 0 
        then 'PE 3 IS DOWN; ' 
       end) || 
       (case when sum(case when pe_id = 1 then 4 else 0 end) = 0 
        then 'PE 4 IS DOWN; ' 
       end) || 
       (case when sum(case when pe_id = 1 then 5 else 0 end) = 0 
        then 'PE 5 IS DOWN; ' 
       end) || 
       (case when sum(case when pe_id = 1 then 6 else 0 end) = 0 
        then 'PE 6 IS DOWN; ' 
       end), 'ALL PROCESS ENGINES ARE UP AND RUNNING') as status 
from CWVMINFO; 

,或者,如果你沒有有單排,你可以這樣做:

select ids.id, 
     (case when count(c.pe_id) = 0 then "DOWN' else 'UP' end) as status 
from (select 1 as id from dual union all select 2 from dual union all select 3 from dual union all 
     select 4 union all select 5 union all select 6 from dual 
    ) ids left join 
    CWVMINFO c 
    on c.pe_id = ids.id 
group by ids.id 
order by ids.id; 

這會讓所有東西都被檢查更明顯。

+0

非常感謝Gordon! – ram81012 2015-02-13 18:26:43