在动态表名称上运行查询

时间:2017-08-08 08:33:16

标签: sql postgresql

我从查询中获取表名,我试图在此表上运行查询。以下是我的代码,

select count(COLUMN_NAME) from TABLE_NAME 
        where (TABLE_NAME,COLUMN_NAME) in 
        (SELECT TABLE_NAME,COLUMN_NAME 
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE COLUMN_NAME IN ('hststr_batch_no','hstdt_expiry_date','hstdt_manuf_date')
        group by TABLE_NAME,COLUMN_NAME )

我尝试通过许多操作符链接它们,但它们似乎都没有用。我怎么能得到这个。

更新:

我试图从我的数据库结构中获取以下格式的数据。

Table Name    Column Name      No of rows in that column in that table
tab_1         batch_no         46
tab_1         mfg_date         46
tab_2         mfg_date         30

目前,我成功地使用以下查询获取包含我想要的列的表名,

-- For tables having all three columns
SELECT TABLE_NAME 
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE COLUMN_NAME IN ('hststr_batch_no','hstdt_expiry_date','hstdt_manuf_date')
group by TABLE_NAME
having count(distinct COLUMN_NAME) = 3  

-- For tables against columns
SELECT TABLE_NAME,COLUMN_NAME 
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE COLUMN_NAME IN ('hststr_batch_no','hstdt_expiry_date','hstdt_manuf_date')
        group by TABLE_NAME,COLUMN_NAME 

现在,当我尝试获取我真正想要的东西时,即给定表中给定列中的行数,我得到了未知表名的错误。那是因为SQL不接受动态表名。帮助

with data as (SELECT TABLE_NAME,COLUMN_NAME 
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE COLUMN_NAME IN ('hststr_batch_no','hstdt_expiry_date','hstdt_manuf_date') )
select table_name, column_name, (select count(*) from table_name) as num from data

1 个答案:

答案 0 :(得分:1)

如果您对近似值没问题,请将数据与pg_stat _...统计数据连接起来,例如:

t=# select schemaname,relname,n_live_tup,column_name 
from pg_stat_user_tables t 
join information_schema.columns c on c.table_name = relname and c.table_schema = schemaname 
where column_name in ('starttime','i');
 schemaname | relname | n_live_tup | column_name
------------+---------+------------+-------------
 public     | intern  |          0 | starttime
 public     | bi      |          4 | i
 public     | i       |          2 | i
 public     | c       |         20 | starttime
 public     | s2      |          2 | i
(5 rows)

如果你想要精确计数(btw可以过时,当你解析结果时,所以不是那么珍贵),你需要一些动态的sql,例如:

t=# do
$$
declare
 _r record;
 _t text;
begin
 for _r in (select c.table_schema,c.table_name, c.column_name from information_schema.columns c where column_name in ('starttime','i')) loop
  execute format ($f$select %L||' '||count(1) from %I.%I$f$,_r.table_schema||' '|| _r.table_name,_r.table_schema, _r.table_name) into _t;
  raise info '%',_t;
 end loop;
end;
$$
;
INFO:  public intern 20
INFO:  public bi 4
INFO:  public i 2
INFO:  public c 20
INFO:  public s2 2
DO
Time: 32.743 ms

顺便说一下,在我的数据样本中,您看到实时计数为一个表格提供了不同的结果"实习生" 20对0.我应该首先分析一下:

t=# analyze verbose public.intern;
INFO:  analyzing "public.intern"
INFO:  "intern": scanned 1 of 1 pages, containing 20 live rows and 20 dead rows; 20 rows in sample, 20 estimated total rows
ANALYZE
Time: 64.210 ms

现在近似将得到与动态sql相同的结果:

t=# select schemaname,relname,n_live_tup,column_name
t-#     from pg_stat_user_tables t
t-#     join information_schema.columns c on c.table_name = relname and c.table_schema = schemaname
t-#     where column_name in ('starttime','i');
 schemaname | relname | n_live_tup | column_name
------------+---------+------------+-------------
 public     | intern  |         20 | starttime
 public     | bi      |          4 | i
 public     | i       |          2 | i
 public     | c       |         20 | starttime
 public     | s2      |          2 | i
(5 rows)