多个/相关子查询

时间:2021-01-03 20:04:16

标签: sql amazon-redshift

我目前在 SQL Workbench/J 和 Redshift 中工作。我仍在学习,并且有一个关于创建依赖于另一个子查询结果的子查询的问题。在下面的示例中,实现了一个子查询以生成按唯一符号分组的多条记录的平均值。然后我在主查询中使用平均值来计算附加值 (USD/UCL/LCL)。但是,我需要在这些聚合值上添加一个 where 子句,但我不能这样做。由于它依赖于要生成的第一个子查询,我将如何实现另一层子查询来预先计算 UCL/LCL?我曾尝试将其添加到第一个子查询中,但未成功。我提前感谢您的帮助,因为我只是在学习。

select 
    symbol, 
    mean,
    avg(volume) as volume,
    (mean * avg(volume) * 0.001) as USD,
    STDV,
    (MEAN + STDV * 3) as UCL,
    (MEAN - STDV * 3) as LCL,
    sum((high > ucl)::int) as ucltest,
    sum((low < lcl)::int) as lcltest
from 
    (select 
         h.*,
         avg(close) over (partition by symbol) as mean,
         cast(stddev_samp(close) over (partition by symbol) as dec(14,2)) as STDV
     from 
         historical h) 
group by 
    symbol, mean, STDV;

1 个答案:

答案 0 :(得分:0)

您不需要另一层查询,但存在问题。第一件事是您需要记住,对于来自子查询的每一行重复的符号的每个值,您都有平均值(和标准差)。这就是为什么您需要对这些进行分组以降低每个符号的单个值。这是一种方法,但由于这些都是相关的,因此最好使用像 MIN(MEAN) 这样的聚合函数作为 MEAN。这也会导致混淆,因为名称为 MEAN 的值有两个。

现在真正的问题是您试图在聚合函数中使用 ucl 和 lcl。这些是查询的这个级别的本地,因此您会看到错误。您只需要对这些值重复计算。像这样(未经测试):

select 
    symbol, 
    min(lmean) as mean,
    avg(volume) as volume,
    (min(lmean) * avg(volume) * 0.001) as USD,
    min(LSTDV) as STDV,
    min(LMEAN + LSTDV * 3) as UCL,
    min(LMEAN - LSTDV * 3) as LCL,
    sum((high > (LMEAN + LSTDV * 3))::int) as ucltest,
    sum((low < (LMEAN - LSTDV * 3))::int) as lcltest
from 
    (select 
         h.*,
         avg(close) over (partition by symbol) as lmean,
         cast(stddev_samp(close) over (partition by symbol) as dec(14,2)) as LSTDV
     from 
         historical h) 
group by 
    symbol
having 
    lcltest = 0 and ucltest = 0; --Having clause excludes any groups with either lcltest or ucltest not equal to 0