2014-01-06 69 views
7

我有一個列出項目和關於這些項目的狀態的表格。問題是有些項目有多個不同的狀態條目。例如。SQL條件案例

HOST   Status 
1.1.1.1  PASS 
1.1.1.1  FAIL 
1.2.2.2  FAIL 
1.2.3.3  PASS 
1.4.2.1  FAIL 
1.4.2.1  FAIL 
1.1.4.4  NULL 

我需要爲每個資產返回一個狀態。

HOST   Status 
1.1.1.1  PASS 
1.2.2.2  FAIL 
1.2.3.3  PASS 
1.4.2.1  FAIL 
1.1.4.4   No Results 

我一直在試圖用T-SQL Case語句來做到這一點,但不能完全得到它的權利。 條件是任何通過+任何事情都是通過,失敗+否結果是失敗,空值是沒有結果。

+2

那麼什麼是規則,爲什麼1.1.1.1的傳遞是期望的而不是失敗。請不要說第一個,除非你有其他專欄,表明他們在什麼順序 –

+0

狀態日期和規則使用最新的,你根本不需要情況下的實例。 –

+0

我會將狀態存儲爲某種數值(比如1或0代表通過/失敗),然後在主機上做一個分組,然後總結狀態,然後對該總數進行邏輯分析... – Rikon

回答

4

嘗試使用case語句轉換爲對結果排序和分組,最後,你需要轉換回好看的,人類可讀的答案:

with cte1 as (
    SELECT HOST, 
     [statNum] = case 
         when Status like 'PASS' then 2 
         when Status like 'FAIL' then 1 
         else 0 
        end 
    FROM table 
) 
SELECT HOST, case max(statNum) when 2 then 'PASS' when 1 then 'FAIL' else 'No Results' end 
FROM cte1 
GROUP BY HOST 

注:我使用的CTE聲明希望讓事情變得更清晰,但一切都可以在一個單一的SELECT來完成,像這樣:

SELECT HOST, 
[Status] = case max(case when Status like 'PASS' then 2 when Status like 'FAIL' then 1 else 0 end) 
    when 2 then 'PASS' 
    when 1 then 'FAIL' 
    else 'No Result' 
    end 
FROM table 
+0

使用相同的查詢可以嵌套CAST語句。我有一個「排除」表,我還需要考慮因素。第一個演員會將狀態設置爲「排除」以匹配主機,然後將此查詢設置爲與排除不匹配的主機 –

+0

@EddieD,我不確定確切地說,你正在嘗試做什麼,但是通常你可以嵌套'cast'語句(和'case'語句,如果這就是你的意思)。所以,給它一個鏡頭,如果你碰到另一面牆,把所有東西放在一起,你總是可以問另一個問題! – chezy525

2

您可以使用Max(Status)Group by Host獲得Distinct值:

Select host, coalesce(Max(status),'No results') status 
From Table1 
Group by host 
Order by host 

Fiddle Demo Results:

| HOST |  STATUS | 
|---------|------------| 
| 1.1.1.1 |  PASS | 
| 1.1.4.4 | No results | 
| 1.2.2.2 |  FAIL | 
| 1.2.3.3 |  PASS | 
| 1.4.2.1 |  FAIL | 

默認情況下,SQL Server是不區分大小寫,如果大小寫是爲您的服務器的關注,然後將其用作低於下限()函數:

Select host, coalesce(Max(Lower(status)),'No results') status 
From Table1 
Group by host 
Order by host 

Fiddle demo

+0

小心!即使'「FAIL」<「PASS」',通常''PASS「<」失敗「'(注意字符的情況) – chezy525

+0

@ chezy525:默認情況下,SQL Server不區分大小寫。區分大小寫也可以使用'Lower()'和'Upper()'函數處理。用法就像'coalesce(Max(Lower(status)),'No results')'。 – Kaf

+0

或者,你可以在聚合函數中強制排序:'max(Status COLLATE Latin1_General_CI_AI)'......我不知道哪一個更有效...... – chezy525

0
WITH CTE(HOST, STATUSValue) 
AS(
    SELECT HOST, 
    CASE STATUS WHEN 'PASS' 1 ELSE 0 END AS StatusValue 
    FROM Data 
) 

SELECT DISTINCT HOST, 
    CASE ISNULL(GOOD.STATUSVALUE,-1) WHEN 1 THEN 'Pass' 
     ELSE CASE ISNULL(BAD.STATUSVALUE,-1) WHEN 0 Then 'Fail' Else 'No Results' END 
    END AS Results 
FROM DATA AS D 
LEFT JOIN CTE AS GOOD 
    ON GOOD.HOST = D.HOST 
AND GOOD.STATUSVALUE = 1 
LEFT JOIN CTE AS BAD 
    ON BAD.HOST = BAD.HOST 
AND BAD.STATUSVALUE = 0