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

Изберете от функцията на PostgreSQL, която връща съставен тип

Postgres 9.3 или по-нова версия

Използвайте LATERAL присъединете се!

SELECT p.id, p.name, p.data, f.*
FROM   tb_projects p
LEFT   JOIN LATERAL fn_getlinkedproject(p.id) f(linked_id, lined_name) ON TRUE;

Резултат:

 id |  data  |  name  | linked_id | linked_name
----+--------+--------+-----------+-------------
  1 | data_1 | name_1 |         2 | name_2
  2 | data_2 | name_2 |         3 | name_3
  3 | data_3 | name_3 |         1 | name_1

Вижте:

Postgres 9.2 или по-стара версия

Непълноценен по няколко причини. Прикачването на псевдоними на колони не е толкова просто. По-скоро преименувайте други противоречиви имена:

SELECT p.id AS p_id, p.data AS p_data, p.name AS p_name, (fn_getlinkedproject(p.id)).*
FROM   tb_projects p;

Резултат:

 p_id | p_data | p_name | id |  name
------+--------+--------+----+--------
    1 | data_1 | name_1 |  2 | name_2
    2 | data_2 | name_2 |  3 | name_3
    3 | data_3 | name_3 |  1 | name_1

За преименуване колоните с резултати, трябва да:

SELECT p.id, p.data, p.name
     ,(fn_getlinkedproject(p.id)).id   AS linked_id
     ,(fn_getlinkedproject(p.id)).name AS linked_name
FROM   tb_projects p;

И двете стари решения решават един и същ (лош) план за заявка за многократно извикване на функцията.

За да избегнете това, използвайте подзаявка:

SELECT p.id, p.data, p.name
    , (p.x).id AS linked_id, (p.x).name AS linked_name
FROM  (SELECT *, fn_getlinkedproject(id) AS x FROM tb_projects) p;

Обърнете внимание на поставянето на основните скоби .
Прочетете ръководството за съставните типове .

Демо

CREATE TYPE dm_nameid AS (
  id   int
, name text); -- types simplified for demo

CREATE TABLE tb_projects(
  id   int
, data text
, name text);

INSERT INTO tb_projects VALUES
  (1, 'data_1', 'name_1')
, (2, 'data_2', 'name_2')
, (3, 'data_3', 'name_3');

CREATE function fn_getlinkedproject(integer)  -- avoiding CaMeL-case for demo
  RETURNS dm_nameid LANGUAGE sql AS
'SELECT id, name FROM tb_projects WHERE id = ($1 % 3) + 1';

db<>fiddle тук




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Възможно ли е да се посочи уникален индекс с разрешени NULL в Rails/ActiveRecord?

  2. Как да ограничим достъпа до база данни в PostgreSQL

  3. PostgreSQL ГРЕШКА:изявление за анулиране поради конфликт с възстановяването

  4. PostgreSQL - Колона с псевдоними и HAVING

  5. NULL елементи се губят при предаване на резултат от unnest()