PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Съхраняване на обща заявка като колона?

Има ли начин да съхраните този подселекция като псевдоколона в таблицата?

A VIEW like е посъветван е напълно валидно решение. Давай.

Но има друг начин, който отговаря на въпроса ви още по-близо. Можете да напишете функция, която приема типа на таблицата като параметър за емулиране "изчислено поле" или „генерирана колона“ .

Помислете за този тестов случай, извлечен от вашето описание:

CREATE TABLE tbl_a (a_id int, col1 int, col2 int);
INSERT INTO tbl_a VALUES (1,1,1), (2,2,2), (3,3,3), (4,4,4);

CREATE TABLE tbl_b (b_id int, a_id int, colx int);
INSERT INTO tbl_b VALUES
  (1,1,5),  (2,1,5),  (3,1,1)
, (4,2,8),  (5,2,8),  (6,2,6)
, (7,3,11), (8,3,11), (9,3,11);

Създайте функция, която емулира col3 :

CREATE FUNCTION col3(tbl_a)
  RETURNS int8
  LANGUAGE sql STABLE AS
$func$
SELECT sum(colx)
FROM   tbl_b b
WHERE  b.a_id = $1.a_id
$func$;

Сега можете да направите заявка:

SELECT a_id, col1, col2, tbl_a.col3
FROM   tbl_a;

Или дори:

SELECT *, a.col3 FROM tbl_a a;

Обърнете внимание как написах tbl_a.col3 / a.col3 , а не само col3 . Това е от съществено значение .

За разлика от „виртуална колона“ в Oracle това ене включен автоматично в SELECT * FROM tbl_a . Можете да използвате VIEW за това.

Защо това работи?

Често срещаният начин за препратка към колона на таблица е с нотация на атрибут :

SELECT tbl_a.col1 FROM tbl_a;

Често срещаният начин за извикване на функция е с функционална нотация :

SELECT col3(tbl_a);

Като цяло е най-добре да се придържате към тези канонични начини , които са в съответствие със стандарта SQL.

Но Postgres също позволява записване на атрибути. Тези също работят:

SELECT col1(tbl_a) FROM tbl_a;
SELECT tbl_a.col3;

Повече за това в ръководството.
Сигурно вече сте виждали накъде води това. Това изглежда както бихте добавили допълнителна колона от таблица tbl_a докато col3() всъщност е функция, която приема текущия ред на tbl_a (или неговия псевдоним) като аргумент за тип ред и изчислява стойност.

SELECT *, a.col3
FROM   tbl_a AS a;

Ако има действителна колона col3 той има приоритет и системата не търси функция с това име, като заема реда tbl_a като параметър.

"Красотата" на това:можете да добавяте или пускате колони от tbl_a и последната заявка ще върне динамично всички текущи колони, където изгледът ще върне само такива колони, които са съществували по време на създаване (ранно обвързване срещу късно обвързване на * ).
Разбира се, трябва да махнете зависимата функция, преди да можете да пуснете таблицата сега. И трябва да внимавате да не отмените функцията, когато правите промени в таблицата.

Все още не бих го използвал. Твърде изненадващо е за невинния читател.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Мигриране от Oracle към PostgreSQL – какво трябва да знаете

  2. PostgreSQL:Автоматично увеличаване на базата на уникално ограничение за няколко колони

  3. Как да конвертирате низ в клеймо за време в PostgreSQL

  4. PostgreSQL тригери и основи на съхранените функции

  5. Основно наблюдение на PostgreSQL – част 1