2016-04-16 5 views
0

Ich habe eine Tabelle mit folgendem FormatWie filtert man Zeilen basierend auf Gruppenwerten in SQL?

serialnumber,test,result 
------------------------- 
ABC   1 "TOO HIGH" 
ABC   2 "PASS" 
ABC   3 "TOO LOW" 
DEF   1 "PASS" 
DEF   2 "PASS" 
DEF   3 "PASS" 

Ich brauche zwei Operationen zu tun:

1) für jede Seriennummer, die alle Pass Aufzeichnungen hat, muss ich es rollen in einem einzigen Datensatz nach oben

2) für jede serielle, die einen „zu hoch“ oder „zu niedrig“ Datensatz enthält, muss ich für diese Seriennummer alle „PASS“ Datensätze auszuschließen

Wie würde ich über das tun dies in teradata gehen 15 vorzugsweise in einer Sünde gle Aussage?

Antwort

1
SELECT * 
FROM tab 
QUALIFY 
    -- #1, only PASS 
    ( SUM(CASE WHEN result <> 'PASS' THEN 1 ELSE 0 end) 
     OVER (PARTITION BY serialnumber) = 0 
    AND ROW_NUMBER() 
     OVER (PARTITION BY serialnumber 
       ORDER BY test) = 1 
) 
OR 
    -- #2 
    ( SUM(CASE WHEN result <> 'PASS' THEN 1 ELSE 0 end) 
     OVER (PARTITION BY serialnumber) > 0 
    AND result_ <> 'PASS' 
) 
1

Betrachten Sie eine Union-Abfrage, die beide Bedingungen kombiniert, indem Sie eine Aggregatabfrage für # 1 und eine innere Join-Abfrage mit abgeleiteten Tabellen für # 2 verwenden. Hoffentlich Teradata Dialekt unterstützt die Syntax:

SELECT TableName.SerialNumber, 
     Min(TableName.Test) As Test, 
     Min(TableName.Result) As Result 
FROM SerialNumber 
GROUP BY SerialNumber 
HAVING Sum(CASE WHEN TableName.Result='"PASS"' THEN 1 ELSE 0 END) = Count(*) 

UNION 

SELECT TableName.SerialNumber, 
     TableName.Test, 
     TableName.Result 
FROM SerialNumber  
INNER JOIN 
     (SELECT SerialNumber FROM SerialNumber 
     WHERE TableName.Result = '"TOO HIGH"') AS toohighSub 
INNER JOIN 
     (SELECT SerialNumber FROM SerialNumber 
     WHERE TableName.Result = '"TOO LOW"') AS toolowSub 
ON toolowSub.SerialNumber = toohighSub.SerialNumber 
ON TableName.SerialNumber = toolowSub.SerialNumber 
WHERE TableName.Result <> '"PASS"'; 
Verwandte Themen