如何从另一个视图创建视图?
How to create a view from an other one?
在 postgreSQL 中,我创建了一个 table 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_a
创建 view_b
(即,不创建列 bar
两次,这对所有视图都是相同的)。
注意:是一个简化的例子,在实践中:
- 有 4 次浏览,不是 2 次;
- 很少有其他列像
foo
;
- 每个视图上有数十个其他列,例如
bar
(带有硬编码数据)。
- 您 "Creating a column" 并不像您在视图中所想的那样。视图不包含任何数据,它只是定义了一种方式,您 "View" 视图引用的基础 table 中的数据。
- 您建议您更改基础 table 以匹配您的视图 B,但如果您这样做,那么视图 A 中的结果将会更改。
- 您已经在 UNION 中合并了您的观点。您可以通过用于定义视图的 SQL 直接引用它们,而不是按名称引用视图。全部都是一样。
因此,在一个查询中:
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 即可。
为了避免一遍又一遍地编写 'Hello' as bar
和其他常量类型字段,您可以使用 CTE(通用 Table 表达式) 在您的 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
在 postgreSQL 中,我创建了一个 table 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_a
创建 view_b
(即,不创建列 bar
两次,这对所有视图都是相同的)。
注意:是一个简化的例子,在实践中:
- 有 4 次浏览,不是 2 次;
- 很少有其他列像
foo
; - 每个视图上有数十个其他列,例如
bar
(带有硬编码数据)。
- 您 "Creating a column" 并不像您在视图中所想的那样。视图不包含任何数据,它只是定义了一种方式,您 "View" 视图引用的基础 table 中的数据。
- 您建议您更改基础 table 以匹配您的视图 B,但如果您这样做,那么视图 A 中的结果将会更改。
- 您已经在 UNION 中合并了您的观点。您可以通过用于定义视图的 SQL 直接引用它们,而不是按名称引用视图。全部都是一样。
因此,在一个查询中:
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 即可。
为了避免一遍又一遍地编写 'Hello' as bar
和其他常量类型字段,您可以使用 CTE(通用 Table 表达式) 在您的 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