【问题标题】:TERADATA: Aggregate across multiple tablesTERADATA:跨多个表聚合
【发布时间】:2012-09-25 16:00:10
【问题描述】:

考虑以下查询,其中聚合发生在两个表中:Sales 和 Promo,并且聚合值再次用于计算。

SELECT

  sales.article_id,
  avg((sales.euro_value - ZEROIFNULL(promo.euro_value)) / NULLIFZERO(sales.qty - ZEROIFNULL(promo.qty)))

FROM
(   SELECT 
         sales.article_id,
         sum(sales.euro_value),
         sum(sales.qty)
    from SALES_TABLE sales
    where year >= 2011
    group by article_id
) sales
LEFT OUTER JOIN
(   SELECT 
         promo.article_id,
         sum(promo.euro_value),
         sum(promo.qty)
    from PROMOTION_TABLE promo
    where year >= 2011
    group by article_id
) promo

ON sales.article_id = promo.article_id

GROUP BY sales.article_id;

关于查询的一些注释:

  1. 由于文章数量众多,两个内部查询都返回大量行。在 teradata 上运行解释,内部查询本身花费的时间非常少,但连接需要很长时间。
  2. 假设 article_id 上的主键存在并且两个表都按年份分区。
  3. 左外连接,因为第二个表包含可选数据。

那么,您能否建议一种更好的方式来编写此查询。感谢您阅读本文:)

【问题讨论】:

  • PROMO 和 SALES 表的主索引是什么?听起来假脱机重新分配或倾斜问题可能会影响您的查询。你也可以分享一下解释吗?
  • 您的两个内部查询都会产生唯一的article_id 值,因为相应的结果按article_id 分组。因此,您不需要在外部查询中按 article_id 分组。尝试摆脱外部分组,看看这是否能以任何方式加速您的查询。
  • 是的,我同意。在此查询中,不需要外部分组依据。但就性能而言,它并没有太大的区别

标签: sql join aggregate-functions teradata


【解决方案1】:

不太确定 avg 函数是如何混入其中的,所以我将其删除。

SELECT article_id,
       (SUM(sales_value) - SUM(promo_value)) /
       (SUM(sales_qty) - SUM(promo_qty))
FROM (
    SELECT 
         article_id,
         sum(euro_value) AS sales_value,
         sum(qty) AS sales_qty,
         0 AS promo_value,
         0 AS promo_qty
    from SALES_TABLE sales
    where year >= 2011
    group by article_id
    UNION ALL
    SELECT 
         article_id,
         0 AS sales_value,
         0 AS sales_qty,
         sum(euro_value) AS promo_value,
         sum(qty) AS promo_qty
    from SALES_TABLE sales
    where year >= 2011
    group by article_id
) AS comb

GROUP BY article_id;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    相关资源
    最近更新 更多