postgresql - 如何将过滤器下推到视图的 group by 子句?
问题描述
我们在项目上有一个第三方 BI 工具,它只能where
在表/视图选择上添加带有指定过滤器的子句。我们使用一组 4 个源表,它们具有可以使用 BI 的 UI 过滤的列的索引。我们为每个按索引列分组并添加 1 个附加列的表都有一个视图。然后我们有另一个视图,它使用索引列连接这 4 个视图中的所有数据,即从我们的 BI 的 UI 查询的视图,BIwhere
向查询添加子句。
问题是没有使用源表上的索引,没有将过滤器推到表级别,而是在最后应用它们。我们不能使用 Set Returning Function,我们的 BI 工具只能从 table\view 中选择并添加一个where
子句。
我们考虑过select
在 Pg 中截取 a 的 where 条件,但我不确定这是否可能。或者,也许可以提示优化器需要下推过滤器。我们可以不使用视图直接查询源表,但它会在 UI 上增加许多数据源\元素,这是不可取的。有没有其他方法可以在 PostgreSQL 中解决它?
更新 1
下面是我们用于表和视图的模式/查询示例
CREATE TABLE source_table_1
(
dim1 VARCHAR(255) NOT NULL,
dim2 VARCHAR(255) NOT NULL,
dim3 VARCHAR(255) NOT NULL,
meausre1 Bigint NOT NULL,
meausre2 Bigint NOT NULL,
meausre3 Bigint NOT NULL
);
CREATE INDEX ON uc13_failures_by_cell (dim1, dim2, dim3);
... another 3 tables
CREATE OR REPLACE VIEW view1 AS
SELECT
"type1" as type,
dim1,
dim2,
dim3,
sum(meausre1) AS meausre1,
sum(meausre2) AS meausre2,
sum(meausre3) AS meausre3
FROM source_table_1
GROUP BY 1, 2, 3, 4;
... another 3 views
CREATE OR REPLACE VIEW view_uinion AS
SELECT
coalesce(view1.dim1, view2.dim1, view3.dim1, view4.dim1) AS dim1,
... two other dims
view1.meausre1 AS meausre1_1,
view2.meausre1 AS meausre2_1,
view3.meausre1 AS meausre3_1,
view4.meausre1 AS meausre4_1,
... two meausres
FROM view1
FULL JOIN view2 ON
view1.dim1 = view2.dim1 AND
view1.dim2 = view2.dim2 AND
view1.dim3 = view2.dim3 AND
FULL JOIN view3 ON ...
FULL JOIN view4 ON ...
WHERE -- this is were filters on dims are inserted
;
解决方案
您不能将WHERE
条件推送到完整的外部联接中。
看这个例子:
CREATE TABLE a(id integer NOT NULL, a1 integer NOT NULL);
INSERT INTO a VALUES (1, 20), (2, 20);
CREATE TABLE b(id integer NOT NULL, b1 integer NOT NULL);
INSERT INTO b VALUES (2, 30), (3, 30);
SELECT *
FROM a
FULL JOIN b USING (id)
WHERE b1 = 30;
id | a1 | b1
----+----+----
2 | 20 | 30
3 | | 30
(2 rows)
SELECT *
FROM a
FULL JOIN (SELECT *
FROM b
WHERE b1 = 30) AS b_red
USING (id);
id | a1 | b1
----+----+----
1 | 20 |
2 | 20 | 30
3 | | 30
(3 rows)
所以你必须修改底层的查询/视图。
如果您使用内部联接,则不会有问题。
推荐阅读
- html - http响应304慢
- javascript - 复制 URL 并粘贴在按钮上,如果“/”后面没有任何内容,则添加默认参数
- java - 在 gradle 中使用 maven-publish 插件生成 SHA512 校验和文件
- java - Jersey 2.11 和 ResourceMethodInvocationHandlerProvider:找不到 MessageBodyWriter
- python - 困难的重复数据删除
- android - Android Studio:依赖版本
- sql - 使用 `jsonb_build_object` 返回具有动态键和聚合值的对象
- dart - Flutter - 在 Google_Sign_In 包中使用 SignInWithEmailAndPassword() 时出现问题
- angular - 在角度应用程序中从后端创建数据模型什么时候有用?
- python - 如何在一组点中找到最近点的子集?