如何从另一个创建视图?

时间:2016-10-14 12:50:53

标签: sql postgresql sql-view

在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_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_b创建view_a (即,不创建列bar两次,这是所有观点都相同。

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

  • 有4个视图,而不是2个;
  • 其他几栏如foo;
  • 每个视图上有数十个其他列,例如bar(带有硬编码数据)。

1 个答案:

答案 0 :(得分:1)

  1. 你不像你在视图中所想的那样“创建一个列”。视图不包含任何数据,它只是您“查看”视图引用的基础表中的数据的方式的定义。
  2. 您建议您更改基础表以匹配您的VIEW B,但如果您这样做,那么视图A中的结果将会更改。
  3. 您已经在UNION中合并了自己的观点。您可以通过用于定义视图的SQL直接引用它们,而不是按名称引用视图。这都一样。
  4. 所以,在一个查询中:

    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