サブクエリなしでこのクエリを書き直すにはどうすればよいですか??
select i.invoice_number, i.invoice_total
from invoices i
where i.invoice_total>(select avg(payment_total)
from invoices);
SELECT は 1 つだけです :-)
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 +で1つの選択のみを使用し、デカルト自己結合なし:)
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
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;
これを行うにはいくつかの方法があります。あなたの教授がそれらを受け入れるとは限りません。
最初の代替案では、最初に関数を作成します。
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;
2 番目の方法は、ビューを作成することです。
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 キーワードが 1 つまたは 2 つ含まれているかどうかを気にする理由が思い浮かびません。1 つの SELECT キーワードのみを使用して 1 つのクエリで上記のすべてを達成するために、開発者が風変わりな/こっけいな/オタクな方法を考え出すことを要求するのは、時間の無駄です。これを迅速かつ賢明に行うための完全に合理的な方法があります。他の方法で誰かに問題を解決するよう求めることは、生産的でも効率的でもないため、IMO では無意味です。
共有してお楽しみください。
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;