在不查询源两次或不使用 CTE 的情况下,基于单个字段聚合整个行?
Aggregate ENTIRE rows based on single field without querying source twice or using CTEs?
假设我有以下 table:
+--------+--------+--------+
| field1 | field2 | field3 |
+--------+--------+--------+
| a | a | 1 |
| a | b | 2 |
| a | c | 3 |
| b | a | 1 |
| b | b | 2 |
| c | b | 2 |
| c | b | 3 |
+--------+--------+--------+
我只想 select 仅 field3
是最小值的行,因此只有这些行:
+--------+--------+--------+
| field1 | field2 | field3 |
+--------+--------+--------+
| a | a | 1 |
| b | a | 1 |
| c | b | 2 |
+--------+--------+--------+
最流行的解决方案是两次查询源,一次直接查询,然后加入子查询,再次查询源,然后聚合。但是,由于我的数据源实际上是派生的 table/subquery 本身,我必须在我的 SQL 中复制子查询,这很丑陋。另一种选择是使用 WITH CTE 并重用子查询,这会很好,但是 Teradata,我正在使用的数据库 ,不支持视图中的 CTE,尽管它在宏中支持这对我来说现在不是一个选择。
那么在标准 SQL 中是否可以通过在聚合中仅使用一个字段将多个记录分组为一个记录 而无需 两次查询源或使用CTE?
如果没有其他行具有相同的 field1 值但具有较低的 field3 值,则使用 NOT EXISTS
到 return 行:
select * from table t1
where not exists (select 1 from table t2
where t2.field1 = t1.field1
and t2.field3 < t1.field3)
这可以使用 window 函数实现:
select *
from (
select column_1, column_2, column_3,
min(column_3) over (partition by column_1) as min_col_3
from the_table
) t
where column_3 = min_col_3;
以上是标准的SQL,相信Teradata也支持window的功能。
派生的 table 是必需的,因为您不能在 where
子句中引用列别名 - 至少在标准 SQL.
中不能
我 认为 Teradata actually allows that 使用 qualify
运算符,但由于我从未使用过它,所以我不确定:
select *
from the_table
qualify min(column_3) over (partition by column_1) = column_3;
假设我有以下 table:
+--------+--------+--------+
| field1 | field2 | field3 |
+--------+--------+--------+
| a | a | 1 |
| a | b | 2 |
| a | c | 3 |
| b | a | 1 |
| b | b | 2 |
| c | b | 2 |
| c | b | 3 |
+--------+--------+--------+
我只想 select 仅 field3
是最小值的行,因此只有这些行:
+--------+--------+--------+
| field1 | field2 | field3 |
+--------+--------+--------+
| a | a | 1 |
| b | a | 1 |
| c | b | 2 |
+--------+--------+--------+
最流行的解决方案是两次查询源,一次直接查询,然后加入子查询,再次查询源,然后聚合。但是,由于我的数据源实际上是派生的 table/subquery 本身,我必须在我的 SQL 中复制子查询,这很丑陋。另一种选择是使用 WITH CTE 并重用子查询,这会很好,但是 Teradata,我正在使用的数据库 ,不支持视图中的 CTE,尽管它在宏中支持这对我来说现在不是一个选择。
那么在标准 SQL 中是否可以通过在聚合中仅使用一个字段将多个记录分组为一个记录 而无需 两次查询源或使用CTE?
如果没有其他行具有相同的 field1 值但具有较低的 field3 值,则使用 NOT EXISTS
到 return 行:
select * from table t1
where not exists (select 1 from table t2
where t2.field1 = t1.field1
and t2.field3 < t1.field3)
这可以使用 window 函数实现:
select *
from (
select column_1, column_2, column_3,
min(column_3) over (partition by column_1) as min_col_3
from the_table
) t
where column_3 = min_col_3;
以上是标准的SQL,相信Teradata也支持window的功能。
派生的 table 是必需的,因为您不能在 where
子句中引用列别名 - 至少在标准 SQL.
中不能
我 认为 Teradata actually allows that 使用 qualify
运算符,但由于我从未使用过它,所以我不确定:
select *
from the_table
qualify min(column_3) over (partition by column_1) = column_3;