1

私はとextended_priceの列を持つorder_linesテーブルを持っています。私はすべての注文の延長価格の合計の平均よりも高い延長価格の合計を持つ注文を知りたい。これは私が得たクエリです:ネストされたサブクエリでの集計へのアクセス

SELECT order_id, SUM(extended_price) AS "sumtotal" 
FROM order_lines e 
GROUP BY order_id 
HAVING SUM(extended_price) > 
    (SELECT AVG(c.sumtotal) AS "avgtotal" 
    FROM 
    (SELECT order_id, SUM(extended_price) AS "sumtotal" 
    FROM order_lines 
    GROUP BY order_id) c 
) 
ORDER BY sumtotal  

私たちは、私がavgtotalを計算するために使用さsumtotalを取得するサブクエリcを持って見ることができるように。しかし、メインクエリと同じクエリを実行してsumtotalを再度計算し、avgtotalと比較します。標準のSQL機能だけを使用してより良い方法がありますか?私はPostgreSQLを使用しています。

答えて

1

一つの方法は、サブクエリでの集合関数の上にウィンドウ関数を実行するために、次のようになります。

SELECT order_id, sumtotal 
FROM (
    SELECT order_id 
     , SUM(extended_price) AS sumtotal 
     , AVG(SUM(extended_price)) OVER() AS avgtotal 
    FROM order_lines 
    GROUP BY order_id 
    ) sub 
WHERE sumtotal > avgtotal; 

は高速にする必要があります。

繰り返し評価を避けるためには、CTEを使用してください。しかし、中間結果の実現にはいくらかのコストがかかります。

WITH cte AS (
    SELECT order_id, SUM(extended_price) AS sumtotal 
    FROM order_lines 
    GROUP BY order_id 
    ) 
SELECT order_id, sumtotal 
FROM cte 
WHERE sumtotal > (SELECT avg(sumtotal) FROM cte); 

明確にするために、平均で別のCTEを使用することがありますが、サブクエリは一般に安価です。

関連:

+0

ありがとう!最近私はSQLで遊んでいることはほとんどないので、ウィンドウの機能に気づいていませんでした。アグリゲートを集約するには最適な方法です。 –

関連する問題