如何在没有子查询的情况下重写此查询?
select i.invoice_number, i.invoice_total
from invoices i
where i.invoice_total>(select avg(payment_total)
from invoices);
只有一个 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)
适合您的变体..在 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
by 来处理行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
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;
这里有几种方法可以做到这一点。我不保证你的教授会接受他们。
对于我们的第一个替代方案,您首先创建一个函数:
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毫无意义。
分享和享受。
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;