如何根据SQL中的组值过滤行?

时间:2016-04-16 09:09:02

标签: sql teradata

我有一个格式如下的表格

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

我需要做两个操作:

1)对于包含所有通过记录的每个序列号,我需要将其汇总到一个记录中

2)对于包含" TOO HIGH"或者"太低"记录,我需要排除所有" PASS"该序列号的记录

我将如何在teradata 15中进行此操作,最好是在一个声明中?

2 个答案:

答案 0 :(得分:1)

考虑结合两个条件的联合查询,使用#1的聚合查询和#2的派生表的内部联接查询。希望Teradata的方言支持语法:

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"';

答案 1 :(得分: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'
  )