返回總行數和選定(聚合)數據
我有一個從表中選擇一些數據的功能。我想返回所選數據和該表中的總行數。
我該如何做到這一點,或者如何以最有效的方式獲得相同的結果?
我嘗試了幾件事,最後得到了下面的程式碼,現在這是我想要的格式,但
count(*) over () as total_count
會一直返回 1,我需要它返回的是該選擇的總行數records
。SELECT row_to_json(selected_records) as data FROM ( SELECT count(*) over () as total_count, array_to_json(array_agg(row_to_json(records))) as data FROM ( SELECT sum(entrances) as entrances FROM report_la WHERE profile_id = 3777614 GROUP BY landing_path_id limit 10 offset 0 ) records ) as selected_records
更新了,下面的程式碼正在產生我想要的結果,如果我可以從選擇中隱藏該
total_count
列會很好records
SELECT row_to_json(selected_records) as data FROM ( SELECT min(total_count) as total_count ,array_to_json(array_agg(row_to_json(records))) as data FROM ( SELECT sum(entrances) as entrances ,count(*) over () as total_count FROM ga.report_la WHERE ga_profile_id = 3777614 GROUP BY landing_path_id limit 10 ) records ) as selected_records
據我了解,您不需要視窗功能。聚合函式可以完成這項工作:
count()
在最低級別 (->row_ct
)。sum()
結果row_ct
進入下一個級別(->total_row_ct
)。SELECT row_to_json(selected_records)::text AS data FROM ( SELECT array_to_json(array_agg(row_to_json(records))) AS data **, sum(row_ct) AS total_row_ct** FROM ( SELECT **landing_path_id** , sum(entrances) AS entrances **, count(*) AS row_ct** FROM report_la WHERE profile_id = 3777614 GROUP BY landing_path_id LIMIT 10 ) records ) selected_records;
我還包括在內
landing_path_id
,因此結果數據是有意義的。視窗功能?
視窗函式 (
count(*) over ()
) 似乎不是您想要的,因為您沒有未聚合的行。您可以添加到內部子查詢:
count(*) OVER ()
.. 獲得 distinct 的計數
landing_path_id
,這是另一個可能感興趣的數字。但這似乎不是您所說的“從該記錄中選擇的總行數”。或者您可以添加到內部子查詢:
sum(count(*)) OVER ()
.. 得到每個冗餘的總數
landing_path_id
,但這似乎毫無意義。只是為了證明可以在一次傳遞中對聚合函式的結果執行視窗函式。詳細資訊:更新的問題
您的結果,只是沒有
total_count
在records
子查詢中。現在佔LIMIT
內裡了SELECT
。即使landing_path_id
選擇了最多 10 個不同的,所有符合條件landing_path_id
的都將被計算在內。為了同時獲得一次掃描和重用計數並分別求和,我引入了一個CTE:
WITH cte AS ( SELECT sum(entrances) AS entrances , **count(*) over () AS total_count** FROM report_la WHERE profile_id = 3777614 GROUP BY landing_path_id LIMIT 10 ) SELECT row_to_json(selected_records)::text AS data FROM ( SELECT (SELECT total_count FROM cte LIMIT 1) AS total_count , array_to_json(array_agg(row_to_json(records))) AS data FROM (SELECT entrances FROM cte) records ) selected_records;
如果您不關心屬性名稱,則可以使用子查詢更便宜:
SELECT row_to_json(selected_records)::text AS data FROM ( SELECT min(total_count) AS total_count , array_to_json(array_agg(row_to_json(**ROW(entrances)**))) AS data FROM ( SELECT sum(entrances) AS entrances , count(*) over () AS total_count -- shouldn't show up in result FROM report_la WHERE profile_id = 3777614 GROUP BY landing_path_id LIMIT 1 ) records ) selected_records;
您將獲得預設屬性名稱
f1
而不是entrances
,因為ROW
表達式不保留列名稱。如果您需要某個屬性名稱,您可以將該行轉換為已註冊的類型。(Ab-)使用 a
TEMP TABLE
為會話註冊我的行類型:CREATE TEMP TABLE rec1 (entrances bigint); ... , array_to_json(array_agg(row_to_json(**ROW(entrances)::rec1**))) AS data ...
這將比 CTE 快一點。或者,更詳細但沒有強制轉換:
... , array_to_json(array_agg(row_to_json( **(SELECT x FROM (SELECT records.entrances) x)**))) AS data ...
此相關答案中的詳細說明: