Oracle SQL联合备选方案

Oracle SQL联合备选方案,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我使用的是OracleSQL11g,假设我们有一个名为TRANSMISSIONS的表,它有一个保存文件大小的字段 我想在不同的分区上执行各种聚合函数,比如说针对不同的文件大小。但是,我希望分区是累积的。 因此,一个10 KB的文件将同时位于中,我们可以将CASE语句编写为 SELECT CASE WHEN tra_size <= 500000 THEN '<=500000' WHEN tra_size <= 2000000000 T

我使用的是OracleSQL11g,假设我们有一个名为TRANSMISSIONS的表,它有一个保存文件大小的字段

我想在不同的分区上执行各种聚合函数,比如说针对不同的文件大小。但是,我希望分区是累积的。
因此,一个10 KB的文件将同时位于中,我们可以将CASE语句编写为

SELECT CASE WHEN tra_size <= 500000 THEN '<=500000' 
                      WHEN tra_size <= 2000000000 THEN  '<=2000000000'
                      END AS label,
COUNT(1) AS numberfiles,
round(AVG(tra_size)) AS averagesize,
SUM(tra_size) AS totalsize
FROM TRANSMISSION
GROUP BY CASE WHEN tra_size <= 500000 THEN '<=500000' 
                      WHEN tra_size <= 2000000000 THEN  '<=2000000000'
                      END;

您正在寻找累计金额。我想我会选择:

SELECT l.label, 
       COUNT(*) AS numberfiles,
       ROUND(AVG(t.tra_size), 2) AS averagesize,
       SUM(t.tra_size) AS totalsize
FROM #TRANSMISSION t JOIN
     (SELECT 1 as ord, '<=500000' as label, 0 as lo, 500000 as hi FROM DUAL UNION ALL
      SELECT 2 as ord, '<=2000000000' as label, 0 as lo, 2000000000 as hi FROM DUAL
     ) l
     ON t.tra_size BETWEEN l.lo AND l.hi
GROUP BY l.label, l.ord
ORDER BY l.ord;
这为您提供了所需范围的充分灵活性-我从0开始,假设这是可能的最小值,但如果不是这样,代码可以调整。

您可以尝试以下方法:

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

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

假设您将最大大小和相应的标签存储在一个小表格中,如下图所示,并且所有文件都有一个“ALL”行,即使是那些大于最大大小列表中最大大小的文件,也包括文件大小为空的文件,你可以这样做:

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;
with
  sample_file_data (file_id, file_size) as (
    select 1001,   10000 from dual union all
    select 1083,   50000 from dual union all
    select 1130,  340000 from dual union all
    select 2323, 1435832 from dual union all
    select 3200,    null from dual union all
    select 1039,   34200 from dual union all
    select 4832, 4320933 from dual
  )
, groups (label, max_size) as (
    select '<=   50000',   50000 from dual union all
    select '<=  200000',  200000 from dual union all
    select '<= 1000000', 1000000 from dual union all
    select 'ALL'       ,    null from dual
  )
-- end of simulated input data; query begins BELOW THIS LINE
select label, count(*) as number_
from   sample_file_data join groups on file_size <= max_size or max_size is null
group  by max_size, label
order  by max_size
;

LABEL         NUMBER_
---------- ----------
<=   50000          3
<=  200000          3
<= 1000000          4
ALL                 7

注意-数字是Oracle关键字,不适合用作列名;我在末尾添加了一个下划线。

这可以通过多个列来实现,然后可以将这些列旋转到行。您可以接受吗?请提供样品data@micklesh是sureCase表达式。这不会带来累积结果,因为当为true并结束语句时,case会立即返回。因此,100码的大小将匹配的情况
with
  sample_file_data (file_id, file_size) as (
    select 1001,   10000 from dual union all
    select 1083,   50000 from dual union all
    select 1130,  340000 from dual union all
    select 2323, 1435832 from dual union all
    select 3200,    null from dual union all
    select 1039,   34200 from dual union all
    select 4832, 4320933 from dual
  )
, groups (label, max_size) as (
    select '<=   50000',   50000 from dual union all
    select '<=  200000',  200000 from dual union all
    select '<= 1000000', 1000000 from dual union all
    select 'ALL'       ,    null from dual
  )
-- end of simulated input data; query begins BELOW THIS LINE
select label, count(*) as number_
from   sample_file_data join groups on file_size <= max_size or max_size is null
group  by max_size, label
order  by max_size
;

LABEL         NUMBER_
---------- ----------
<=   50000          3
<=  200000          3
<= 1000000          4
ALL                 7