我已经找到了答案,但没找到。
所以我有一张桌子types
CREATE TABLE types
(
type_id serial NOT NULL,
type_name character varying,
CONSTRAINT un_type_name UNIQUE (type_name)
)
包含类型名称,例如users
- 这是相应表users
的名称。这个设计可能有点难看,但它是为了让用户创建自己的类型。 (有更好的方法可以解决这个问题吗?)
现在我想执行像这样的查询:
select type_name, (select count(*) from ???) from types
获取所有类型名称的列表和每种类型的对象数。
可以这样做吗?
答案 0 :(得分:5)
您不能直接在SQL
中执行此操作您可以使用PLpgSQL函数和动态SQL
CREATE OR REPLACE FUNCTION tables_count(OUT type_name character varying, OUT rows bigint)
RETURNS SETOF record AS $$
BEGIN
FOR tables_count.type_name IN SELECT types.type_name FROM types
LOOP
EXECUTE 'SELECT COUNT(*) FROM ' || quote_ident(tables_count.type_name) INTO tables_count.rows;
RETURN NEXT;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
SELECT * FROM tables_count();
答案 1 :(得分:4)
我没有足够的信息,但我确实怀疑你的设计出了什么问题。每种类型都不需要额外的表格。
尽管如此,在纯SQL中无法完成您想要做的事情。 它可以通过执行动态SQL的plpgsql函数来完成:
CREATE OR REPLACE FUNCTION f_type_ct()
RETURNS TABLE (type_name text, ct bigint) AS
$BODY$
DECLARE
tbl text;
BEGIN
FOR tbl IN SELECT t.type_name FROM types t ORDER BY t.type_name
LOOP
RETURN QUERY EXECUTE
'SELECT $1, count(*) FROM ' || tbl::regclass
USING tbl;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
呼叫:
SELECT * FROM f_type_ct();
你需要研究大部分chapter about plpgsql in the manual来了解这里发生了什么。
一个特殊提示:cast to regclass
是对SQLi的保护。您也可以使用更普遍适用的quote_ident()
,但这不能正确处理模式限定的表名,而转换为regclass
。它还只接受主叫用户可见的表名。