我有以下查询返回基本唯一行的最小值,最大值和用户总数 在两个不同的表格中。
select sum(user_count) as user_count_sum, sum(min_count) as min_count_sum,
sum(max_count) as max_count_sum
from(
select max(case when di = 'i' then di_count end) as user_count,
min(di_count) as min_count,
max(di_count) as max_count
from (
select di,
count(distinct rt) as di_count
from gpstablev2
where rt > GETDATE() - '1 day'::INTERVAL
group by di
)
UNION
select max(case when di = 'i' then di_count end) as user_count,
min(di_count) as min_count,
max(di_count) as max_count
from (
select di,
count(distinct rt) as di_count
from powertablev2
where rt > GETDATE() - '1 day'::INTERVAL
group by di
)
)
现在我还有一个主表,如果我要运行以下查询将返回以下
select table from mastertable;
gpstablev2
powertablev2
...(more table names)
有没有一种方法可以使用查询mastertable
清除它,而不是粘贴另外9个UNION块,就像我必须对mastertable
中列出的所有表进行求和一样?“ p>
如果我在java中执行此操作,我将首先从主表中获取ResultSet,然后自己执行10次查询和UNION
。但我宁愿让我的数据库进行所有处理,并能够根据mastertable
的内容进行更新。
编辑: 基于反馈我正在尝试动态查询并且已经达到了这个目标,但我仍然无法将其余部分组合在一起
CREATE OR REPLACE FUNCTION get_sums()
RETURNS TABLE(user_count_sum bigint, min_count_sum bigint, max_count_sum bigint)
$BODY$
BEGIN
RETURN QUERY EXECUTE "
SELECT $$SELECT sum(user_count) AS user_count_sum
,sum(min_count) AS min_count_sum
,sum(max_count) AS max_count_sum
FROM (
SELECT max(case when di = 'id' then di_count end) AS user_count
,min(di_count) AS min_count
,max(di_count) AS max_count
FROM ($$
||
string_agg(format($$
(SELECT di, count(distinct rt) AS di_count
FROM %I
WHERE rt > now() - interval '1 day'
GROUP BY 1)$$, tbl)
,'
UNION ALL')
|| '
) sub1
) sub2'
FROM mastertable;
INTO results_var"
END;
$BODY$
LANGUAGE plpqsql;
答案 0 :(得分:0)
您需要动态SQL 。 SQL不接受将文字/值动态转换为标识符。因此,您需要先构建查询然后执行它。您可以在您的客户端(似乎是Java)中执行此操作,或者在Postgres中执行 all ,这通常是最快的:
SELECT $$SELECT sum(user_count) AS user_count_sum
,sum(min_count) AS min_count_sum
,sum(max_count) AS max_count_sum
FROM (
($$
||
string_agg(format($$
SELECT max(case when di = 'i' then di_count end) AS user_count
,min(di_count) AS min_count
,max(di_count) AS max_count
FROM (
SELECT di, count(distinct rt) AS di_count
FROM %I
WHERE rt > now() - interval '1 day'
GROUP BY 1
) t
)$$, tbl)
,'
UNION ALL
(')
|| '
) sub'
FROM mastertable;
生成查询字符串:
SELECT sum(user_count) AS user_count_sum
,sum(min_count) AS min_count_sum
,sum(max_count) AS max_count_sum
FROM (
(
SELECT max(case when di = 'i' then di_count end) AS user_count
,min(di_count) AS min_count
,max(di_count) AS max_count
FROM (
SELECT di, count(distinct rt) AS di_count
FROM gpstablev2
WHERE rt > now() - interval '1 day'
GROUP BY 1
) t
)
UNION ALL
(
SELECT max(case when di = 'i' then di_count end) AS user_count
,min(di_count) AS min_count
,max(di_count) AS max_count
FROM (
SELECT di, count(distinct rt) AS di_count
FROM powertablev2
WHERE rt > now() - interval '1 day'
GROUP BY 1
) t
)
UNION ALL
...
) sub;
GETDATE()
不是有效的Postgres功能。您可能需要now()
或CURRENT_DATE
..这取决于未公开的rt
类型。我改用 now()
。
您很可能希望在此使用 UNION ALL
而不是UNION
。
还修复了子查询中缺少的别名,并进行了一些小的简化。
使用EXECUTE
将其包装到 plpgsql 函数中。有plenty of closely related examples here on SO代码,链接和说明......