当它们存在时,如何检查两列并查询每个表?

时间:2013-08-16 15:57:47

标签: postgresql postgresql-8.4

当“blob”列存在时,我有兴趣为整个数据库执行COUNT(*)SUM(LENGTH(blob)/1024./1024.)ORDER BY SUM(LENGTH(blob))。对于同步级别不存在的表格,我仍然需要输出。我想GROUP BY该列:

实施例

+--------+------------+--------+-----------+
|  table | synchlevel | count  |  size_mb  |
+--------+------------+--------+-----------+
| tableA |          0 | 924505 |   3013.47 |
| tableA |          7 |    981 |    295.33 |
| tableB |          6 |   1449 |    130.50 |
| tableC |          1 |  64368 |     68.43 |
| tableD |       NULL |    359 |       .54 |
| tableD |       NULL |    778 |       .05 |
+--------+------------+--------+-----------+

我想做一个纯SQL解决方案,但我遇到了一些困难。目前,我正在将一些SQL包装到BASH中。

#!/bin/bash

USER=$1
DBNAME=$2

function psql_cmd(){
    cmd=$1
    prefix='\pset border 2 \\ '
    echo $prefix $cmd | psql -U $USER $DBNAME | grep -v "Border\| row"
}

function synchlevels(){
    echo "===================================================="
    echo "                 SYNCH LEVEL STATS                  " 
    echo "===================================================="
    tables=($(psql -U $USER -tc "SELECT table_name FROM information_schema.columns
    WHERE column_name = 'blob';" $DBNAME))
    for table in ${tables[@]}; do
        count_size="SELECT t.synchlevel,
                        COUNT(t.blob) AS count,
                        to_char(SUM(LENGTH(t.blob)/1024./1024.),'99999D99') AS size_mb
                      FROM $table AS t
                      GROUP BY t.synchlevel
                      ORDER BY SUM(LENGTH(t.blob)) DESC;"
        echo $table
        psql_cmd "$count_size"
    done
    echo "===================================================="
}

我可以通过创建第二个具有'synchlevel'列的表的 BASH数组来扩展它,比较并使用该列表来运行SQL,但我想知道是否有我只能在SQL中执行SQL部分而不需要在BASH中创建这些列表并在外部进行比较。即我希望避免需要外部循环遍历表并在tables=($(psql -U $USER...中进行大量查询。

我已经尝试了以下SQL来测试我知道该列不存在的表...

SELECT
  CASE WHEN EXISTS(SELECT * FROM information_schema.columns 
                WHERE column_name = 'synchlevel' 
            AND table_name = 'archivemetadata')
      THEN synchlevel
    END,
  COUNT(blob) AS count,
  to_char(SUM(LENGTH(blob)/1024./1024.),'99999D99') AS size_mb
 FROM archivemetadata, information_schema.columns AS info
 WHERE info.column_name = 'blob'

但是,对于不存在的表,它在THEN synchlevel上失败。这似乎很简单,但我似乎无法找到一种不需要的方法:

  1. 在BASH中使用外部数组比较。
    • 可以做到,但我想简化我的解决方案,而不是添加另一层。
  2. 创建PL / PGSQL函数。
    • 此脚本实际上只是为了帮助进行某些数据库数据分析,以提高第三方软件的性能。我们不是DB Admins的商店,所以我不想深入PL / PGSQL,因为这需要我们商店的更多人也熟悉该语言以支持脚本。再一次,简单就是这里的动力。
  3. Postgresql 8.4是引擎。 (由于监督IT机构的安全限制,我们无法升级。)

    感谢您提出任何建议!

1 个答案:

答案 0 :(得分:1)

以下是未经测试的,但如何在一个psql会话中创建一些动态sql并将其传递给另一个?

psql -d <yourdb> -qtAc "
select  'select ' || (case when info.column_name = 'synchlevel' then 'synchlevel,' else '' end) ||
        'count(*) as cnt,' ||
        'to_char(SUM(LENGTH(blob)::NUMERIC/1024/1024),''99999D99'') AS size_mb' ||
        'from ' || info.table_name ||
        (case when info.column_name = 'synchlevel' then ' group by synchlevel order by synchlevel' else '' end)
from information_schema.columns as info
where info.table_name IN (select distinct table_name from information_schema.columns where column_name = 'blob')" | psql -d <yourdb>