Postgres从多个表中找到最大列值

时间:2019-01-08 13:20:26

标签: postgresql

我有一些具有特定列名的表的列表,例如

SELECT table_name
FROM information_schema.columns
WHERE column_name = 'column1'

我需要找到每个表的column1的最大值。我希望得到如下结果

|--------|--------------|
| Table  |  Max column1 |
|--------|--------------|
| Table1 |     100      |
| Table2 |     200      |
|  ...   |     ...      |
|--------|--------------|

如何构造查询?

2 个答案:

答案 0 :(得分:1)

您可以使用row count for all tables方法的变体:

select t.table_name, 
       (xpath('/row/max/text()', xmax))[1]::text::int
from (
  SELECT table_name, data_type, 
         query_to_xml(format('select max(%I) from %I.%I', column_name, table_schema, table_name), true, true, '') as xmax
  FROM information_schema.columns
  WHERE column_name = 'column1'
    and table_schema = 'public'
) as t;

query_to_xml()为查询返回的每一列运行select max(..) from ..。结果是:

<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <max>42</max>
</row>

然后使用xpath()函数从XML中提取值。派生表(子查询)并不是真正需要的,但是使xpath()表达式更具可读性(我认为)。

答案 1 :(得分:0)

您可以通过从TABLE构造一个UNION ALL查询来创建一个返回information_schema.columns类型的泛型函数

CREATE OR REPLACE FUNCTION public.get_max(TEXT )
RETURNS  TABLE(t_table_name  TEXT, t_max text )
LANGUAGE plpgsql
AS $BODY$
DECLARE
p_colname        TEXT := $1;
v_sql_statement TEXT;

BEGIN

SELECT STRING_AGG( 'SELECT '''||table_name||''','||' MAX('
       || column_name||'::text'
       || ')  FROM '
       || table_name 
         ,' UNION ALL ' ) INTO v_sql_statement
FROM   information_schema.columns 
WHERE  column_name = p_colname 
      --and table_schema = 'public';

    IF v_sql_statement IS NOT NULL THEN
       RETURN QUERY EXECUTE  v_sql_statement;
    END IF;
END
$BODY$;

执行并获得这样的结果。

knayak=# select * FROM get_max('id');
 t_table_name | t_max
--------------+-------
 f            | 2
 t2           | 1
 friends      | id4
 person       | 2
 customer     |
 employe      |
 diary        | 4
 jsontable    | 6
 atable       |
 t_json       | 2
 ingredients  | 1
 test         | 2
 accts        |
 mytable      | 30
(14 rows)