如何从另一个视图创建视图?

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_aview_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_viewview_aview_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_aview_b有很多共同的内容,只是有些栏目不同。所以我想避免冗余并创建 view_a,然后从 view_a 创建 view_b (即,不创建列 bar 两次,这对所有视图都是相同的)。

注意:是一个简化的例子,在实践中:

  • 有 4 次浏览,不是 2 次;
  • 很少有其他列像 foo ;
  • 每个视图上有数十个其他列,例如 bar(带有硬编码数据)。
  1. 您 "Creating a column" 并不像您在视图中所想的那样。视图不包含任何数据,它只是定义了一种方式,您 "View" 视图引用的基础 table 中的数据。
  2. 您建议您更改基础 table 以匹配您的视图 B,但如果您这样做,那么视图 A 中的结果将会更改。
  3. 您已经在 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