当“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
上失败。这似乎很简单,但我似乎无法找到一种不需要的方法:
Postgresql 8.4是引擎。 (由于监督IT机构的安全限制,我们无法升级。)
感谢您提出任何建议!
答案 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>