sec*_*ast 3 postgresql query precedence
我有一个"customer_config"
包含这些列的表:
company (varchar)
warehouse (numeric)
section (numeric)
config_keyword (varchar)
config_value (varchar)
Run Code Online (Sandbox Code Playgroud)
这两config_*
列可以应用于整个公司(warehouse
和section
为空)、公司内的整个仓库(section
为空)或仓库内的一个部分。
因此,我们可以为公司设置一个默认行,然后使用一个或多个行来覆盖特定仓库或仓库和部分的配置值。
我只想返回给定公司、仓库和部门的最具体的行。像这样的伪代码:
results = select * from customer_config where (all match)
if results empty
results = select * from customer_config where (company_code and warehouse match)
if results empty
results = select * from customer_config where (company_code matches)
Run Code Online (Sandbox Code Playgroud)
最具体的行应优先。
同一级别上可以有多个相同的条目config_keyword
。
是否也可以为单个关键字返回多行?
在寻找单个结果行时(如您原来的问题所示):
这有点冗长,但非常清晰,如果支持索引,可能是最快的-(company_code, warehouse, section)
就像你应该有的那样(取决于未公开的信息)。
SELECT * FROM customer_config
WHERE (company_code, warehouse, section) = ($1, $2, $3)
UNION ALL
SELECT * FROM customer_config
WHERE (company_code, warehouse) = ($1, $2)
UNION ALL
SELECT * FROM customer_config
WHERE company_code = $1
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
一旦发现一行,Postgres 将停止执行。使用 进行测试EXPLAIN ANALYZE
,您将看到剩余的子选择“从未执行”。
请注意,LIMIT 1
适用于整个查询,而不是最后一个SELECT
。(您需要括号来更改它。)类似:
如果每个级别上可以存在多行。
当然可以用纯SQL来解决。例如,CTE 链。但这个自定义 PL/pgSQL 函数应该更高效:
CREATE OR REPLACE FUNCTION trade_volume (_company_code varchar, _warehouse numeric, _section numeric)
RETURNS SETOF customer_config
LANGUAGE plpgsql STABLE PARALLEL SAFE AS
$func$
BEGIN
RETURN QUERY
SELECT * FROM customer_config
WHERE (company_code, warehouse, section) = ($1, $2, $3);
IF FOUND THEN RETURN; END IF;
RETURN QUERY
SELECT * FROM customer_config
WHERE (company_code, warehouse) = ($1, $2);
IF FOUND THEN RETURN; END IF;
RETURN QUERY
SELECT * FROM customer_config
WHERE company_code = $1;
END
$func$;
Run Code Online (Sandbox Code Playgroud)
称呼:
SELECT * FROM trade_volume ('my_comany_code', 123456, 123);
Run Code Online (Sandbox Code Playgroud)
一定要有上面提到的索引。
如果第一个查询返回任何行,则该函数完成。其余的甚至没有计划。ETC。
有关的:
PARALLEL SAFE
我在 Postgres 14 或更高版本中创建了允许并行的函数。(仅与大表相关。)引用发行说明:
允许 plpgsql
RETURN QUERY
使用并行性执行其查询 (Tom Lane)