PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Wybierz z funkcji PostgreSQL, która zwraca typ złożony

Postgres 9.3 lub nowszy

Użyj LATERAL dołącz!

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;

Wynik:

 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

Zobacz:

Postgres 9.2 lub starszy

Gorszy z kilku powodów. Dołączanie aliasów kolumn nie jest takie proste. Zamiast tego zmień nazwy innych sprzecznych nazw:

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

Wynik:

 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

Aby zmienić nazwę kolumny wyników, musisz:

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;

Oba stare rozwiązania prowadzą do tego samego (słabego) planu zapytań polegającego na wielokrotnym wywoływaniu funkcji.

Aby tego uniknąć, użyj podzapytania:

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;

Zwróć uwagę na rozmieszczenie podstawowych nawiasów .
Przeczytaj podręcznik dotyczący typów złożonych .

Demo

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 tutaj




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak przekonwertować uniksowy znacznik czasu na wartość daty/godziny w PostgreSQL?

  2. PostgreSQL - Przypisz wartość całkowitą do ciągu w instrukcji case

  3. Dlaczego Postgres pozwala mi mieć kolumny nie w grupie według?

  4. Zapobieganie sąsiednim/nakładającym się wpisom za pomocą EXCLUDE w PostgreSQL

  5. 'Nie można znaleźć pg-0.12.2 w żadnym ze źródeł' podczas uruchamiania rspec