Roc*_*nja 6 postgresql aggregate window-functions postgresql-9.3
我有一个从表格中选择一些数据的功能。我想返回所选数据和该表中的总行数。
我怎样才能做到这一点,或者我怎样才能以最有效的方式获得相同的结果?
我尝试了几件事,最后得到了下面的代码,现在这是我想要的格式,但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
Run Code Online (Sandbox Code Playgroud)
更新,下面的代码产生了我想要的结果,如果我可以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
Run Code Online (Sandbox Code Playgroud)
据我了解,您不需要窗口函数。聚合函数完成这项工作:
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;Run Code Online (Sandbox Code Playgroud)
我也包括在内,landing_path_id所以结果数据是有道理的。
窗口函数 ( count(*) over ()) 似乎不是您想要的,因为您没有未聚合的行。
您可以添加到内部子查询:
count(*) OVER ()
Run Code Online (Sandbox Code Playgroud)
.. 获得 distinct 的计数landing_path_id,这是另一个可能感兴趣的数字。但这似乎不是您所说的“该记录选择的总行数”的意思。
或者您可以添加到内部子查询:
sum(count(*)) OVER ()
Run Code Online (Sandbox Code Playgroud)
.. 获得每个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;Run Code Online (Sandbox Code Playgroud)
如果您不关心属性名称,则可以使用子查询更便宜:
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;Run Code Online (Sandbox Code Playgroud)
您将获得默认属性名称f1而不是entrances,因为ROW表达式不保留列名称。
如果您需要某个属性名称,您可以将该行转换为注册类型。(Ab-) 使用 aTEMP TABLE为会话注册我的行类型:
CREATE TEMP TABLE rec1 (entrances bigint);
...
, array_to_json(array_agg(row_to_json(ROW(entrances)::rec1))) AS data
...Run Code Online (Sandbox Code Playgroud)
这会比 CTE 快一点。或者,更详细但没有强制转换:
...
, array_to_json(array_agg(row_to_json(
(SELECT x FROM (SELECT records.entrances) x)))) AS data
...Run Code Online (Sandbox Code Playgroud)
此相关答案中的详细说明:
| 归档时间: |
|
| 查看次数: |
24976 次 |
| 最近记录: |