在没有子查询的情况下重写avg

时间:2013-03-28 08:51:11

标签: oracle subquery average

如何在没有子查询的情况下重写此查询?

select i.invoice_number, i.invoice_total 
  from invoices i 
 where i.invoice_total>(select avg(payment_total) 
                          from invoices);

5 个答案:

答案 0 :(得分:2)

只有一个SELECT :-)

select i1.invoice_number, i1.invoice_total 
from invoices i1, invoices i2 
group by i1.invoice_number, i1.invoice_total 
having i1.invoice_total > avg(i2.payment_total)

答案 1 :(得分:1)

你的变种......在10g +上只使用一个选择而没有笛卡尔自连接:)

SQL> select avg(payment_total)
  2    from invoices;

AVG(PAYMENT_TOTAL)
------------------
               5.4

SQL> select invoice_number, invoice_total, payment_total
  2    from invoices
  3  model return updated rows
  4  dimension by (row_number() over (order by 1) rn,
  5                case when invoice_total > avg(payment_total) over () then 1 else 2 end a)
  6  measures (invoice_total, invoice_number, payment_total)
  7  rules  (
  8     invoice_number[any, 1] = invoice_number[cv(rn), 1]
  9  )
 10   order by 1;

INVOICE_NUMBER INVOICE_TOTAL PAYMENT_TOTAL
-------------- ------------- -------------
             6             6             1
             7             7             8
             8             8             4
             9             9             7
            10            10             6

“返回更新的行”..我们只返回我们触及的行。我们用case when invoice_total > avg(payment_total) over () then 1 else 2 end a标记每行是否超过平均值。即这些行平均值a设置为1。然后我们只用1 invoice_number[any, 1] = invoice_number[cv(rn), 1]来勾选行(即不要更改任何数据......只需将其更新为自己)。

与原始查询相比:

SQL> select i.invoice_number, i.invoice_total , i.payment_total
  2    from invoices i
  3   where i.invoice_total>(select avg(payment_total)
  4                            from invoices)
  5   order by 1;

INVOICE_NUMBER INVOICE_TOTAL PAYMENT_TOTAL
-------------- ------------- -------------
             6             6             1
             7             7             8
             8             8             4
             9             9             7
            10            10             6

答案 2 :(得分:0)

select
  invoice_number,
  invoice_total
from (
  select 
    invoice_number,
    invoice_total ,
    avg(payment_total) over () avg_payment_total
  from
    invoices)
where
  invoice_total>avg_payment_total;

答案 3 :(得分:0)

这有几种方法可以做到。我不保证你的教授会接受他们。

首先,我们首先创建一个函数:

CREATE OR REPLACE FUNCTION AVG_PAYMENT_TOTAL_FUNC RETURN NUMBER IS
  nAvg_payment_total  NUMBER;
BEGIN
  SELECT AVG(PAYMENT_TOTAL)
    INTO nAvg_payment_total
    FROM INVOICES;

  RETURN nAvg_payment_total;
END AVG_PAYMENT_TOTAL_FUNC;

然后在查询中使用该函数:

select i.invoice_number, i.invoice_total 
  from invoices i 
  where i.invoice_total > AVG_PAYMENT_TOTAL_FUNC;

第二种选择是创建一个视图:

CREATE OR REPLACE VIEW AVG_PAYMENT_TOTAL_VIEW AS
  SELECT AVG(PAYMENT_TOTAL) AS AVG_PAYMENT_TOTAL
    FROM INVOICES;

然后您的查询变为

SELECT i.INVOICE_NUMBER,
       i.INVOICE_TOTAL,
       t.AVG_PAYMENT_TOTAL
  FROM INVOICES i
  CROSS JOIN AVG_PAYMENT_TOTAL_VIEW t;

如果没有这样的话,我就看不到完成你所分配的方法了。更重要的是,我无法想象为什么有人会关心查询中是否有一个或两个SELECT关键字。要求开发人员提出一些古怪/令人讨厌/讨厌的方式来在一个只有一个SELECT关键字的查询中完成上述所有操作,这是浪费时间。有完全合理的方法可以快速,明智地完成这项工作;要求某人解决问题,否则既不高效又无效,因此IMO毫无意义。

分享并享受。

答案 4 :(得分:0)

with average as (select avg(payment_total) avgtot
                 from invoices)
select i.invoice_number, i.invoice_total 
  from invoices i 
  ,    average a
 where i.invoice_total>a.avgtot;