サブクエリなしで結果を取得するには 、高度なウィンドウ関数のトリックに頼る必要があります:
SELECT sum(count(*)) OVER () AS tickets_count
, sum(min(a.revenue)) OVER () AS atendees_revenue
FROM tickets t
JOIN attendees a ON a.id = t.attendee_id
GROUP BY t.attendee_id
LIMIT 1;
sqlfiddle
どのように機能しますか?
これを理解するための鍵は、一連のイベントです。 クエリ内:
集計関数->ウィンドウ関数->DISTINCT->LIMIT
詳細:
- LIMITが適用される前に結果カウントを取得するための最良の方法
ステップバイステップ:
-
GROUP BY t.attendee_id
-これは通常、サブクエリで行います。 -
次に、カウントを合計して、チケットの総数を取得します。あまり効率的ではありませんが、要件によって強制されます。集計関数
count(*)
ウィンドウ関数sum( ... ) OVER ()
でラップされます あまり一般的ではない式に到達するには:sum(count(*)) OVER ()
。そして、参加者1人あたりの最小収益を合計して、重複のない合計を取得します。
max()
を使用することもできます またはavg()
min()
の代わりにrevenue
と同じ効果があります 参加者ごとにすべての行で同じであることが保証されています。DISTINCT
の場合、これはより簡単になる可能性があります ウィンドウ関数で許可されていましたが、PostgreSQLは(まだ)この機能を実装していません。ドキュメントごと:集計ウィンドウ関数は、通常の集計関数とは異なり、
DISTINCT
を許可しません またはORDER BY
関数の引数リスト内で使用されます。 -
最後のステップは、単一の行を取得することです。これは
DISTINCT
で行うことができます (SQL標準)すべての行が同じであるため。LIMIT 1
ただし、高速になります。または、SQL標準形式のFETCH FIRST 1 ROWS ONLY
。