仅选择列包含特定数值的表

时间:2012-02-19 17:54:14

标签: sql postgresql database-design plpgsql

是否可以仅选择列(AD_CLIENT_ID)包含特定数值(1000000)的表?

我有850个表可供选择,每个表都有此列,但并非所有列都包含1000000。

2 个答案:

答案 0 :(得分:2)

嗯..

  • 强烈重新考虑您的设计。
  • 查看巨大的UNION结构 在所有表中,然后查询WHERE AD_CLIENT_ID = 100000

答案 1 :(得分:1)

您可以使用执行动态SQL的plpgsql函数获取表的列表,循环遍历目录中的结果。考虑以下演示,在PostgreSQL 9.1上进行测试,但至少应该使用8.4版本甚至更早版本:

CREATE OR REPLACE FUNCTION f_tbl_with_value(numeric)
  RETURNS SETOF text AS
$BODY$
DECLARE
    _tbl text;
BEGIN

FOR _tbl IN
    SELECT DISTINCT quote_ident(n.nspname) || '.' || quote_ident(c.relname)
    FROM   pg_catalog.pg_attribute a
    JOIN   pg_catalog.pg_class c ON c.oid = a.attrelid
    JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE  a.attname = 'ad_client_id'
    AND    a.attisdropped = FALSE -- column hasn't been dropped
    AND    n.nspname = 'myschema' -- search only this schema
    AND    c.relkind = 'r'  -- only real tables
LOOP    
    RETURN QUERY EXECUTE '
    SELECT ''' || _tbl || '''::text
    WHERE  EXISTS (
        SELECT *
        FROM   ' || _tbl || '
        WHERE  ad_client_id = $1
        )'
    USING $1;
END LOOP;

END;
$BODY$
  LANGUAGE plpgsql;

呼叫:

SELECT * FROM x.f_tbl_with_value(100000)

重点

  • 结果是列ad_client_id所在的表名列表,其中包含至少一行中的参数值。

  • 我使用PostgreSQL目录。您可以像在评论中演示的那样使用SQL标准信息架构。但这速度要慢很多,只有在你想保持代码可移植性时才有用。由于这个plpgsql函数无法移植到其他数据库系统,我使用更快的PostgreSQL目录表。

  • 请注意我如何使用纯SQL来检索表名,但dynamic SQL来查询它们。

  • 请注意我如何在架构和表名上使用quote_ident()来防止SQL注入,并在需要时自动保留混合大小写标识符。

  • 我使用小写字符串'ad_client_id'作为列名。或者你真的需要大写,因为你在创建它时双引"AD_CLIENT_ID"? (我通常建议仅使用小写标识符。More about that in the manual.

相关问题