首页 > 解决方案 > Oracle SQL UNION 替代方案

问题描述

我正在使用ORACLE SQL(11g),假设我们有一个名为的表,该表TRANSMISSIONS的字段包含file sizes

partitions我想针对不同的文件大小执行各种聚合函数。但是我希望分区是累积的。所以一个10 KB文件将同时在<=500000 bytes分区和<=2000000000分区中。因此,如果我有 5 个文件<=500000和 5 个文件,> 50000 && < 2000000000那么我将得到以下结果:

   label       | number
---------------|-------
<=500000       | 5
<=2000000000   | 10

所以基本上最初的方法是做这样的联合:

SELECT '<=500000' as label,
       COUNT(1) AS numberFiles,
       round(avg(tra.TRA_SIZE)) as averageSize,
       sum(tra.TRA_SIZE) as totalSize
FROM TRANSMISSION tra
where tra.TRA_SIZE <= 500000

UNION

SELECT '<=2000000000' as label,
       COUNT(1) AS numberFiles,
       round(avg(tra.TRA_SIZE)) as averageSize,
       sum(tra.TRA_SIZE) as totalSize
FROM TRANSMISSION tra
where tra.TRA_SIZE <= 2000000000;

但是,如果我有几个partitions这样的操作,它将导致一个巨大的不可维护的查询,其中唯一改变的基本上是labelandwhere子句。

有没有更好的方法来做到这一点?

标签: sqloracleoracle11g

解决方案


你可以试试这个:

WITH limits(n) AS (
SELECT 500000 FROM DUAL
UNION ALL 
SELECT n+500000 FROM limits 
WHERE n < 10000000
)
SELECT
   '<=' || to_char(n,'00000000') AS label,
   round(avg(tra.TRA_SIZE)) as averageSize,
   sum(tra.TRA_SIZE) as totalSize
FROM TRANSMISSION tra
CROSS JOIN limits
WHERE tra.TRA_SIZE <= n
GROUP BY n
ORDER BY n

不过,您可能想要更改限制。


推荐阅读