有一个表,里面有关于汽车的数据。
model_id | color |
---|---|
1 | 黑色 |
1 | 绿色 |
2 | 黑色 |
3 | 蓝色 |
3 | 白色 |
4 | 红色 |
5 | 白色 |
5 | 黑色 |
我只需使用:
select c.*
from cars c
where c.color = 'black' or
not exists (select 1
from cars c2
where c2.model_id = c.model_id and
c2.color = 'black'
);
在许多情况下,您可能会发现窗口函数具有良好的性能:
select c.*
from cars c
qualify c.color = 'black' or
sum(case when c.color = 'black' then 1 else 0 end) over (partition by c.model_id) = 0;
至于所有版本中哪一个版本的性能最好,那么你必须在你的数据和系统上尝试它们。这取决于许多因素:
- 表上的索引
- 桌子的大小
- 每个模型的平均颜色数
- 黑色/非黑色颜色的数量在模型之间的分布
可能更多。上面的其中一个似乎是合理的——不涉及临时表的方法也是合理的。
这是另一种基于OLAP函数的方法,可以很容易地扩展到更复杂的逻辑:
SELECT *
FROM cars
QUALIFY
Rank()
Over (PARTITION BY model_id
-- preferred condition first
ORDER BY CASE WHEN color = 'black' THEN 1 ELSE 0 END DESC) = 1
;
Teradata中OLAP函数的性能可能与基于EXISTS等的解决方案一样好或更好。只有PARTITION BY列上的PI可能会超过它,这主要取决于每个值的行数。