我mydata在 Postgres 14 資料庫中有一個表,其中包含以下相關列:
ftype:enum擁有foo,bar和bazstatus: 另一個enum有pending,failed,success
我想要不同型別的成功率。成功率基本上是: 的行數status除以success的總行數ftype。
目前,我正在執行以下操作:
SELECT
COALESCE(
COUNT(CASE WHEN ftype = 'foo' AND status = 'success' THEN 1 END) /
NULLIF(COUNT(CASE WHEN ftype = 'foo' THEN 1 END)::real, 0)
,0)::real AS foo_rate,
COALESCE(
COUNT(CASE WHEN ftype = 'bar' AND status = 'success' THEN 1 END) /
NULLIF(COUNT(CASE WHEN ftype = 'bar' THEN 1 END)::real, 0)
,0)::real AS bar_rate,
COALESCE(
COUNT(CASE WHEN ftype = 'baz' AND status = 'success' THEN 1 END) /
NULLIF(COUNT(CASE WHEN ftype = 'baz' THEN 1 END)::real, 0)
,0)::real AS baz_rate,
FROM mydata;
有沒有更好/更高效的方法?我該如何優化它?在查詢中
使用會有幫助嗎?PARTITION
uj5u.com熱心網友回復:
由于您正在計算所有型別的費率,因此旋轉結果會更簡單:
SELECT ftype, CASE WHEN ct_success = 0 THEN 0 ELSE ct_success/ct_total END AS rate
FROM (
SELECT ftype
, count(*) AS ct_total
, count(*) FILTER (WHERE status = 'success')::real AS ct_success
FROM mydata
GROUP BY 1
) sub;
也適用于多種型別。(不過,好處較小。)及早過濾:
SELECT ftype, CASE WHEN ct_success = 0 THEN 0 ELSE ct_success/ct_total END AS rate
FROM (
SELECT ftype
, count(*) AS ct_total
, count(*) FILTER (WHERE status = 'success')::real AS ct_success
FROM mydata
WHERE ftype = ANY ('{foo,bar,baz}'::my_enum_type[]) -- here!
GROUP BY 1
) sub;
關于WHERE條款:
- PostgreSQL 中的 IN 與 ANY 運算子
您可能想要round()和/或使用numeric開始。看:
- 如何將 REAL 型別四舍五入為 NUMERIC?
- 數值的四舍五入
關于聚合FILTER子句:
- 使用其他(不同的)過濾器聚合列
從我們掌握的最少資訊中很難判斷表磁區是否有幫助。在“表磁區”手冊“概述”一章中有有用的指南。我有根據的猜測是它不會使您受益。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/533256.html
標籤:sqlPostgreSQL查询优化postgresql 性能
下一篇:如何在SQL中宣告或設定多個值?
