我如何修复我的(复杂)查询,以便它给我正确的表?

时间:2014-12-01 23:41:02

标签: mysql sql math subquery nested-queries

所以我有这个问题:

SELECT a.year, a.avg_kw_price, b.avg_kw_consumed
From (select year, avg(value) as avg_kw_price 
 from AP_DATA where substring(series_id, 8) ='72610' 
 group by year)a, 
(select substring(YYYYMM,1,4) as year, Value*9506632 as avg_kw_consumed 
from RESIDENTIAL_EN_CONSUMPTION where MSN = 'ESRCBUS' and  
substring(YYYYMM, 4,2) = '13' 
group by substring(YYYYMM,1,4)) b
WHERE a.year = b.year;

我的两个表格如下:AP_DATA :( 72610部分指的是项目kw / h)

series_id           year    period      value
APU000072610        1996    M11        0.092              
APU000072610        1996    M12        0.092              
APU000072610        1997    M01        0.092              
APU000072610        1997    M02        0.092              
APU000072610        1997    M03        0.093              
APU000072610        1997    M04        0.092

表RESIDENTIAL_EN_CONSUMPTION看起来像这样(YYYYMM项目末尾的13表示当年的总数):

MSN      YYYYMM     Value    Description    Unit
ESRCBUS  201008      200     Electricity    Trillion btu
ESRCBUS  201112      396     Electricity    Trillion btu
ESRCBUS  201113      1200    Electricity    Trillion btu
ESRCBUS  201213      2000    Electricity    Trillion btu

我希望我的桌子看起来像是这样的:

year     avg_kw_price      avg_kw_consumed
2011     1.2                 158049
2012     0.9                 120310

截至目前,我正在使用查询即时获取空表。此外,你可以看到我乘以9506632的价值,因为我做了一些数学,这就是你如何从每年万亿btu到kw /小时。然而,这并不重要,我不确定它是否正确,所以如果我必须将它拿出并保持在btu。我如何修复我的查询,以便它实际上给我一个我想要的表,如果你愿意,忽略单位转换?

2 个答案:

答案 0 :(得分:0)

意识到我的第二个子串写得不正确。它应该是子串(YYYYMM,5,2)而不是子串(YYYYMM4,2)。有时是小事。如果它对任何其他人都有用,我会保持开放状态。

答案 1 :(得分:0)

我经常使用的策略是:使用您需要的数据创建临时表,在它们上创建适当的索引,然后将所有数据放在一起(换句话说:分而治之策略)。

那么,让我们看看可以做些什么:

-- Your subquery "a":
drop table if exists temp_step01;
create temporary table temp_step01
    select year, avg(value) as avg_kw_price 
    from AP_DATA 
    where substring(series_id, 8) ='72610' 
    group by year;
alter table temp_step01
    add index idx_year(year);
-- Your subquery "b":
-- I'll split the process in two, to ease things a bit
drop table if exists temp_step02;
create temporary table temp_step02
    select cast(substring(YYYYMM,1,4) as unsigned int) as year -- It's easier to 
                                                               -- handle numbers
         , Value*9506632 as avg_kw_consumed 
    from RESIDENTIAL_EN_CONSUMPTION 
    where MSN = 'ESRCBUS';
alter table temp_step02
    add index idx_year(year);
drop table if exists temp_step03;
create temporary table temp_step03
    select year
         , avg_kw_consumed -- I think you should aggregate this value somehow
    from temp_step02
    group by year;
-- Finally:
select a.year, avg_kw_price, avg_kw_consumed
from temp_step01 as a
     inner join temp_step03 as b on a.year = b.year

您应该检查所有计算是否正确,但我认为这个想法很明确:

  1. 过滤第一个表中的数据并将其放在临时表中。

    将所有适当的索引添加到此表中。

  2. 过滤第二个表中的数据并将其放入另一个临时表中。

    将所有适当的索引添加到此表中。

  3. 做你需要做的任何计算。如果需要,请使用其他临时表。

    我坚持认为:将所有适当的索引添加到此表中。

  4. 在最后一个简单的查询中提取您需要的所有数据。
  5. 使用临时表执行所有“繁重”任务:过滤,聚合等。关键是分开执行这些步骤,并在最后将它们全部放在一起,使用每个步骤的索引字段来优化相应的连接。

    请记住:临时表仅对创建它们的连接可见,并在连接关闭或终止后被删除。