0

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

例子

+--------+------------+--------+------------+
| 表| 同步级别 | 计数 | 大小_mb |
+--------+------------+--------+------------+
| 表A | 0 | 924505 | 3013.47 |
| 表A | 7 | 981 | 295.33 |
| 表B | 6 | 第1449章 130.50 |
| 表C | 1 | 64368 | 68.43 |
| 表D | 空 | 359 | .54 |
| 表D | 空 | 第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 "===================================================="
}

我可以通过创建第二个BASH 表数组来扩展它,这些表具有“synchlevel”列,比较并使用该列表来运行 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,因为这需要我们商店的更多人也熟悉该语言才能支持脚本。同样,简单是这里的动机。

Postgresql 8.4 是引擎。(由于监管 IT 机构的安全限制,我们无法升级。)

感谢您提出的任何建议!

4

1 回答 1

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>
于 2013-08-16T16:42:59.517 回答