PostgreSQL-как я могу заменить нулевые значения значениями из другого столбца на основе общего уникального идентификатора в представлении PSQL
У меня есть три внешних идентификатора в моем представлении PSQL. Как я могу заменить нулевые значения second_id на значения third_id, основанные на их общем first_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 На самом деле является CASE WHEN модификацией 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
Еще раз спасибо за вашу помощь.
2 ответов:
Вы не можете
UPDATEнижележащую таблицу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'у вас есть ровно 1third_idзначение; если нет, вы должны добавить соответствующие квалификаторы, такие какORDER BY first_id ASC NULLS LAST LIMIT 1или какой-либо другой подходящий фильтр. Также обратите внимание, что CTE являетсяJOINed, а неLEFT JOINed, предполагая, что всегда существует допустимая пара(first_id, third_id)БезNULLs.
Вы можете получить его по:
select a.first_id, coalesce(a.second_id,b.second_id), a.third_id from my_table a left outer join ( select first_id, second_id from my_table where second_id is not null ) b using (first_id)Поэтому обновление должно быть:
update my_table a set second_id = b.second_id from ( select first_id, second_id from my_table where second_id is not null ) b where b.first_id = a.first_id and a.second_id is null
Comments