Oracle SQL中的查询改进

时间:2014-12-01 17:21:17

标签: sql oracle sequential

我需要写一个硬查询,我需要一些帮助。

我有下表(MyTable

C1 int,
C2 int,
C3 int,
.
.
C79 int
C80 int

请注意:这些列名称是假的。真正的列名称不相似。每列都有自己的名称,与其他任何列都不相似。

我有以下查询(queryA):

select cnt / (select count(*) from MyTable)
  from (
    select c1, c2, count(*) over(partition by c1, c2) cnt
     from MyTable);

我需要为每个连续列运行此查询:C(i) - C(i + 1),C(i + 1) - C(i + 2)...在上面的查询中,我运行它对于c1和c2。

此外,我还有两个类似的查询,例如上面的查询。在输出表中,每个连续列将从3个查询中进行3次计算。

输出表看起来像那样(所有列类型都应该是float):

c12A - calculation of query A for c1-c2
c12B - calculation of query B for c1-c2
c12C - calculation of query C for c1-c2
c23A - calculation of query A for c2-c3
c23B - calculation of query B for c2-c3
c23C - calculation of query C for c2-c3
.
.
.
c7980A - calculation of query A for c79-c80
c7980B - calculation of query B for c79-c80
c7980C - calculation of query C for c79-c80

我希望很清楚。任何建议如何做到这一点?

1 个答案:

答案 0 :(得分:0)

WITH t1 AS (
SELECT 'MYTABLE' nm FROM dual
),
t2 AS (
select rw, c1, c2 from (
    SELECT column_id rw, column_name c1, 
           lead(column_name) OVER(ORDER BY column_id) c2 FROM cols CROSS JOIN t1 
    WHERE table_name = t1.nm
  ) WHERE c2 IS NOT NULL
)
SELECT 0 rw, 'select rw,n/n_all from (select count(*) n_all from ' || nm || ') cross join ('  FROM t1
UNION ALL
SELECT rw, CASE WHEN rw > 1 THEN 'union all ' END || 'select ' || rw 
           || ' rw, count(*) over(partition by ' || c1 || ', ' || c2 || ') n from ' || t1.nm 
FROM t2 CROSS JOIN t1
UNION ALL
SELECT 10000 rw, ') order by rw'  FROM dual
order by rw;  

您可以使用Oracle字典cols(= user_tab_columns)生成查询字符串。

我使用cols.column_id来定义列的“顺序”:lead(column_name) OVER(ORDER BY column_id)