在postgreSQL中,我创建了一个表my_table
:
DROP SCHEMA IF EXISTS roipoussiere cascade;
CREATE SCHEMA roipoussiere;
CREATE TABLE roipoussiere.my_table (
id SERIAL PRIMARY KEY,
x smallint,
y smallint);
INSERT INTO roipoussiere.my_table(x, y) VALUES (42, 42);
-- [etc.]
...我创建了视图view_a
和view_b
,它们具有相同的列(但内容不同):
DROP VIEW IF EXISTS roipoussiere.view_a CASCADE;
CREATE VIEW roipoussiere.view_a AS SELECT
concat_ws('view_a_', x, '_', y) AS foo,
'Hello' AS bar,
x,
y
FROM roipoussiere.my_table;
DROP VIEW IF EXISTS roipoussiere.view_b CASCADE;
CREATE VIEW roipoussiere.view_b AS SELECT
concat_ws('view_b_', x, '_', y) AS foo,
'Hello' AS bar,
x,
y
FROM roipoussiere.my_table;
...然后我创建了视图my_view
,view_a
和view_b
的联合:
DROP VIEW IF EXISTS roipoussiere.my_view CASCADE;
CREATE VIEW roipoussiere.my_view AS
SELECT * FROM roipoussiere.view_a UNION ALL
SELECT * FROM roipoussiere.view_b;
但是view_a
和view_b
有很多共同的内容,只有一些列是不同的。所以我想避免冗余并创建view_a
,然后从 view_b
创建view_a
(即,不创建列bar
两次,这是所有观点都相同。
注意:这是一个简化的例子,在实践中:
foo
; bar
(带有硬编码数据)。答案 0 :(得分:1)
所以,在一个查询中:
Create VIEW roipoussiere.view_c AS
SELECT
concat_ws('view_a_', x, '_', y) AS foo,
'Hello' AS bar,
x,
y
FROM roipoussiere.my_table
UNION ALL
SELECT
concat_ws('view_b_', x, '_', y) AS foo,
'Hello' AS bar,
x,
y
FROM roipoussiere.my_table;
每当您发现自己在视图之上创建视图时(在视图顶部的视图之上),问问自己是否真的需要这些基础视图。你会自己执行ViewA,还是只是让View C更易于编写?如果你不需要它,那就不要创建它,只需在最终视图中的子查询中执行SELECT。
为了一次又一次地将每个SELECT语句写成'Hello' as bar
和其他常量类型字段,你可以使用CTE(公用表表达式)来定义它一次在你的1个视图中,一遍又一遍地使用它。
CREATE VIEW roipoussiere.view_c as
WITH myCTE AS
(
SELECT
'Hello' AS bar,
'Goodbye' as f1,
'Another constant' as f2
x,
y
FROM roipoussiere.my_table
)
SELECT
concat_ws('view_a_', x, '_', y) AS foo,
bar,
f1,
f2,
x,
y
FROM myCTE
UNION ALL
SELECT
concat_ws('view_b_', x, '_', y) AS foo,
bar,
f1,
f2,
x,
y
FROM myCTE