2014-01-06 5 views
7

Ich habe eine Tabelle, die Elemente und einen Status über diese Elemente auflistet. Das Problem besteht darin, dass einige Elemente mehrere unterschiedliche Statuseinträge aufweisen. Beispielsweise.SQL Conditional Case

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 

Ich muss einen Status pro Asset zurückgeben.

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 

Ich habe versucht, dies mit T-SQL-Case-Anweisungen zu tun, aber es kann nicht ganz richtig. Die Bedingungen sind alle Pass + alles ist ein Pass, Fail + No Ergebnisse sind ein Fehler und Null ist keine Ergebnisse.

+2

Also, was sind die Regeln, warum ist der Pass für 1.1.1.1 gewünscht, anstatt der Fehler. Bitte sagen Sie nicht das erste, es sei denn, Sie haben eine andere Spalte, die angibt, in welcher Reihenfolge sie sich befinden. –

+0

Mit einem Statusdatum und einer Regel, die die letzte verwendet, brauchen Sie gar keine Eingabe. –

+0

Ich würde Status als etwas numerisches speichern (wie 1 oder 0 für Bestehen/Nichtbestehen) und dann eine Gruppe durch auf dem Wirt tun und den Status addieren und dann Ihre Falllogik auf dieser Summe tun ... – Rikon

Antwort

4

Versuchen Sie, eine case Anweisung zu geordneten Ergebnisse und Gruppe auf, dass zu konvertieren, schließlich werden Sie zurück zu den schönen, menschenlesbare Antwort konvertieren müssen:

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 

HINWEIS: benutzte ich einen CTE Anweisung, um hoffentlich die Dinge ein wenig klarer, aber alles konnte in einem einzigen SELECT, wie so geschehen:

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

Mit derselben Abfrage ist es möglich, die CAST-Anweisungen zu verschachteln. Ich habe eine "Ausschlüsse" -Tabelle, die ich auch berücksichtigen muss. Die erste Besetzung wäre, den Status als Ausschluss für passende Hosts zu setzen, dann diese Abfrage für die Hosts, die nicht mit dem Ausschluss übereinstimmen –

+0

@EddieD, ich bin mir nicht sicher Genau, was du versuchst zu tun, aber generell kannst du 'cast'-Anweisungen verschachteln (und' case'-Anweisungen, falls du das meinst). Also, versuchen Sie es, und wenn Sie an eine andere Wand stoßen, die alles zusammenstellt, können Sie immer eine andere Frage stellen! – chezy525

2

Sie Max(Status) mit Group by Host können Distinct Werte erhalten:

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 | 

standardmäßig SQL Server ist Groß- und Kleinschreibung, wenn Groß- und Kleinschreibung ein Anliegen für den Server ist, dann verwenden Sie die untere() Funktion wie folgt:

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

Fiddle demo

+0

Sei vorsichtig damit! Obwohl "FAIL" <"PASS" ', oft" "PASS" <"fail" '(beachten Sie den Fall der Zeichen) – chezy525

+0

@ chezy525: Standardmäßig wird bei SQL Server nicht zwischen Groß- und Kleinschreibung unterschieden. Die Groß-/Kleinschreibung kann auch mit den Funktionen "Lower()" und "Upper()" behandelt werden. Verwendung wäre wie 'coalesce (Max (Lower (Status)), 'No results')'. – Kaf

+0

alternativ könnten Sie eine Sortierung in der Aggregatfunktion erzwingen: 'max (Status COLLATE Latin1_General_CI_AI)' ... Ich weiß nicht, was effizienter ist ... – 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