如何根据 SQL 中的组值过滤行?
How to filter rows based on group values in SQL?
我有一个table格式如下
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" 或 "TOO LOW" 记录的序列,我需要排除该序列号的所有 "PASS" 记录
我将如何在 teradata 15 中执行此操作,最好是在单个语句中?
考虑结合两个条件的联合查询,对#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"';
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'
)
我有一个table格式如下
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" 或 "TOO LOW" 记录的序列,我需要排除该序列号的所有 "PASS" 记录
我将如何在 teradata 15 中执行此操作,最好是在单个语句中?
考虑结合两个条件的联合查询,对#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"';
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'
)