小弟做报表统计的时候遇到个问题 
有table1 table2 table3 三张表,表结构一样,有time area amount 三个字段且都是varchar型table1:
time  area amount
20110501 北京  100
20110501 上海  111
20110502 北京  100
20110502 上海  111
20110503 北京  100
20110503 上海  111
20110504 北京  100
20110504 上海  111table2:
time  area amount
20110501 北京  200
20110501 上海  222
20110502 北京  200
20110502 上海  222
20110503 北京  200
20110503 上海  222
20110504 北京  200
20110504 上海  222table3:
time  area amount
20110501 北京  300
20110501 上海  333
20110502 北京  300
20110502 上海  333
20110503 北京  300
20110503 上海  333
20110504 北京  300
20110504 上海  333现在我想实现查询 
time area table1.amount table2.amount table3.amount
20110501~20110503 北京 300 600 900
20110501~20110503 上海 333 666 999以后还可能有更多的表,所以希望查询能适应,求高手指点...操作系统  WIN7旗舰版7601
oracle版本 11G R2

解决方案 »

  1.   

    1、这种无限增加表的方式设计不太合理,一般来说,如果数据量大,应该使用分区。
    2、如果非要这样做,可以使用动态拼接SQL。
      

  2.   


    WITH base_table AS(
    SELECT TIME,AREA,AMOUNT,1 type_id FROM table1
    UNION ALL SELECT TIME,AREA,AMOUNT,2 FROM table2
    UNION ALL SELECT TIME,AREA,AMOUNT,3 FROM table3
    )SELECT min_time||'~'||max_time  data_time,area,
    sum(decode(type_id,1,AMOUNT,0)) AMOUNT1,
    sum(decode(type_id,2,AMOUNT,0)) AMOUNT2,
    sum(decode(type_id,3,AMOUNT,0)) AMOUNT3 FROM 
    (SELECT MIN(TIME) min_time, max(TIME) max_time,area,SUM(AMOUNT)  AMOUNT,type_id FROM base_table
    GROUP BY area,type_id)
    GROUP BY min_time,max_time,area;
      

  3.   

    额···有些东西没说清楚,补充一下吧,时间是用户选择的开始和结束时间,至于 20110501~20110503 只是举个例子。SQL语句也是在程序拼接的。参考5楼的回复
    我自己改改实现了功能,这里先多谢5楼lizhuxin2008的指教。以下是我改后的SQLWITH base_table AS(
    SELECT TIME,AREA,AMOUNT,1 type_id FROM table1 WHERE TIME between '20110501' and '20110503'
    UNION ALL SELECT TIME,AREA,AMOUNT,2 FROM table2 WHERE TIME between '20110501' and '20110503'
    UNION ALL SELECT TIME,AREA,AMOUNT,3 FROM table3 WHERE TIME between '20110501' and '20110503'
    )SELECT '20110501' || '~' || '20110503' data_time,
           area,
           sum(decode(type_id, 1, AMOUNT, 0)) AMOUNT1,
           sum(decode(type_id, 2, AMOUNT, 0)) AMOUNT2,
           sum(decode(type_id, 3, AMOUNT, 0)) AMOUNT3
      FROM (SELECT '20110501' min_time,
                   '20110503' max_time,
                   area,
                   SUM(AMOUNT) AMOUNT,
                   type_id
              FROM base_table
             GROUP BY area, type_id)
     GROUP BY min_time, max_time, area;这是在程序里拼接的String startTime = "20110501"; //Model.getStartTime();
    String endTime   = "20110503"; //Model.getEndTime();
    String sql   = "WITH base_table AS( "
    + "SELECT TIME,AREA,AMOUNT,1 type_id FROM table1 WHERE TIME between '" + startTime + "' and '" + endTime + "' "
    + "UNION ALL SELECT TIME,AREA,AMOUNT,2 FROM table2 WHERE TIME between '" + startTime + "' and '" + endTime + "' "
    + "UNION ALL SELECT TIME,AREA,AMOUNT,3 FROM table3 WHERE TIME between '" + startTime + "' and '" + endTime + "' ) "
    + "\r\n "
    + "SELECT '" + startTime + "' || '~' || '" + endTime + "' data_time, "
    + "area, "
    + "sum(decode(type_id, 1, AMOUNT, 0)) AMOUNT1, "
    + "sum(decode(type_id, 2, AMOUNT, 0)) AMOUNT2, "
    + "sum(decode(type_id, 3, AMOUNT, 0)) AMOUNT3 "
    + "FROM (SELECT '" + startTime + "' min_time, "
    + "'" + endTime + "' max_time, "
    + "area, "
    + "SUM(AMOUNT) AMOUNT, "
    + "type_id "
    + "FROM base_table "
    + "GROUP BY area, type_id) "
    + "GROUP BY min_time, max_time, area ";
      

  4.   

    oracle分区表