PostgreSQL – 如何根据PSQL VIEW中的公共唯一标识符将NULL值替换为来自另一列的值

我的PSQL视图中有三个外部标识符.我怎么能用基于公共first_id的third_id值替换NULL second_id值?

目前:


 first_id | second_id | third_id 
----------+-----------+----------
        1 |           |      11
        1 |           |      11
        1 |           |      11
        1 |        22 |      22
        2 |        33 |      33
        3 |        44 |      44
        4 |        55 |      55
        5 |        66 |      66
        6 |           |      77
        6 |           |      77
        6 |           |      77
        6 |           |      77
        6 |        88 |      88

应该:


 first_id | second_id | third_id 
----------+-----------+----------
        1 |        22 |      11
        1 |        22 |      11
        1 |        22 |      11
        1 |        22 |      22
        2 |        33 |      33
        3 |        44 |      44
        4 |        55 |      55
        5 |        66 |      66
        6 |        88 |      77
        6 |        88 |      77
        6 |        88 |      77
        6 |        88 |      77
        6 |        88 |      88

我怎样才能做出这个改变?

>应填充second_id列中的NULL值,即不应有空单元格.
>如果second_id列与third_id列共享一个值,则此值应填充second_id列中的空白单元格.
>他们都应该基于他们共同的first_id.

非常感谢.对此,我真的非常感激.

second_id实际上是修改third_id时的情况.在视图中进行此修改.

视图:

    View "public.my_view"
               Column            |            Type             | Modifiers | Storage  | Description 
    -----------------------------+-----------------------------+-----------+----------+-------------
     row_number                  | bigint                      |           | plain    | 
     first_id                    | integer                     |           | plain    | 
     second_id                   | integer                     |           | plain    | 
     third_id                    | integer                     |           | plain    | 
     first_type                  | character varying(255)      |           | extended | 
     date_1                      | timestamp without time zone |           | plain    | 
     date_2                      | timestamp without time zone |           | plain    | 
     date_3                      | timestamp without time zone |           | plain    | 
    View definition:
     SELECT row_number() OVER (PARTITION BY t.first_id) AS row_number,
        t.first_id,
            CASE
                WHEN t.localization_key::text = 'rq.bkd'::text THEN t.third_id
                ELSE NULL::integer
            END AS second_id,
        t.third_id,
        t.first_type,
            CASE
                WHEN t.localization_key::text = 'rq.bkd'::text THEN t.created_at
                ELSE NULL::timestamp without time zone
            END AS date_1,
            CASE
                WHEN t.localization_key::text = 'st.appt'::text THEN t.created_at
                ELSE NULL::timestamp without time zone
            END AS date_2,
            CASE
                WHEN t.localization_key::text = 'st.eta'::text THEN t.created_at
                ELSE NULL::timestamp without time zone
            END AS date_3
       FROM my_table t
      WHERE (t.localization_key::text = 'rq.bkd'::text OR t.localization_key::text = 'st.appt'::text OR t.localization_key::text = 'st.eta'::text) AND t.first_type::text = 'thing'::text
      ORDER BY t.created_at DESC;

以下是视图正在使用的表定义的链接(my_table).

https://gist.github.com/dankreiger/376f6545a0acff19536d

再次感谢你的帮助.

最佳答案 您无法更新基础表my_table,因为它没有second_id列,因此您应该使视图以您希望的方式显示数据. CTE相当简单:

CREATE VIEW my_view AS
  WITH second (first, id) AS (
    SELECT first_id, third_id
    FROM my_table
    WHERE t.localization_key = 'rq.bkd')
  SELECT
    row_number() OVER (PARTITION BY t.first_id) AS row_number,
    t.first_id,
    s.id AS second_id,
    t.third_id,
    t.first_type,
    CASE
      WHEN t.localization_key = 'rq.bkd' THEN t.created_at
    END AS date_1,
    CASE
      WHEN t.localization_key = 'st.appt' THEN t.created_at
    END AS date_2,
    CASE
      WHEN t.localization_key = 'st.eta' THEN t.created_at
    END AS date_3
  FROM my_table t
  JOIN second s ON s.first = t.first_id
  WHERE (t.localization_key = 'rq.bkd'
     OR t.localization_key = 'st.appt'
     OR t.localization_key = 'st.eta')
    AND t.first_type = 'thing'
  ORDER BY t.created_at DESC;

这假设你的my_table.localization_key =’rq.bkd’确实有1个third_id值;如果不是,您应该添加适当的限定符,例如ORDER BY first_id ASC NULLS LAST LIMIT 1或其他一些合适的过滤器.另请注意,CTE是JOINed,而不是LEFT JOINed,假设始终存在没有NULL的有效对(first_id,third_id).

点赞