参考 Amazon Redshift 查询中的聚合结果?

Refer to aggregate result in Amazon Redshift query?

在其他 postgresql 数据库管理系统(例如 Netezza)中,我可以毫无错误地做这样的事情:

select store_id
      ,sum(sales) as total_sales
      ,count(distinct(txn_id)) as d_txns
      ,total_sales/d_txns as avg_basket
from my_tlog
group by 1

即,我可以在定义它们的同一个 SQL 查询中使用聚合值。

然而,当我在 Amazon Redshift 上做同样的事情时,我得到了错误 "Column total_sales does not exist..." 它没有,这是正确的;它不是真正的专栏。但是有没有办法保留这个习语,而不是重构查询呢?我问是因为会有很多代码要更改。

谢谢。

您只需重复表达式(或使用子查询或 CTE):

select store_id,
       sum(sales) as total_sales,
       count(distinct txn_id) as d_txns,
       sum(sales)/count(distinct txn_id) as avg_basket
from my_tlog
group by store_id;

大多数数据库支持在select中重复使用列别名。原因有两个(至少):

  • 数据库引擎的设计者不想在 select 中指定表达式的处理顺序。
  • 当列别名也是 from 子句中 table 中的有效列时,会出现歧义。

就我个人而言,我喜欢 netezza 中的结构。这样简洁,语法也没有歧义:任何'dublicate'列名在当前查询中都会默认为(new)别名,如果需要引用底层表的列,只需将表名放在前面即可专栏。上面的例子会变成:

select store_id
  ,sum(sales) as sales                ---- dublicate name
  ,count(distinct(txn_id)) as d_txns
  ,my_tlog.sales/d_txns as avg_basket --- this illustrates but may not make sense
from my_tlog
group by 1

我最近离开了 sql 服务器,在那个数据库上我使用了这样的结构来避免重复表达式:

Select *, total_sales/d_txns as avg_basket
From (
    select store_id
    ,sum(sales) as total_sales
    ,count(distinct(txn_id)) as d_txns
    from my_tlog
    group by 1
)x

大多数(如果不是全部)数据库将支持这种结构,并且已经这样做了 10 年或更长时间