2015-04-14 2 views
1

У меня есть довольно обычная таблица, которая имеет внешний ключ к другой таблице; например:Получение значения списка для каждой строки (список идентификаторов из другой таблицы)

CREATE TABLE table_a (
    id serial NOT NULL, 
    name text, 
    CONSTRAINT table_a_pkey PRIMARY KEY (id) 
); 
CREATE TABLE table_b (
    id serial NOT NULL, 
    a_id integer,  -- The foreign key 
    CONSTRAINT table_b_pkey PRIMARY KEY (id), 
    CONSTRAINT table_b_a_id_fkey FOREIGN KEY (a_id) 
     REFERENCES table_a (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
); 
INSERT INTO table_a 
    VALUES (1, 'First row'); 
-- 2 entries in table_b which refer to the existing table_a row: 
INSERT INTO table_b 
    VALUES (11, 1), (12, 1); 

Теперь я хотел бы иметь представление, которое дает мне список всех идентификаторами table_b строк, которые относятся к текущему table_a ряду:

SELECT a.name, 
     (SELECT b.id 
      FROM table_b b 
     WHERE b.id = a.id) AS b_ids 
    FROM table_a a; 

Однако b_ids колонка пусто; Я хотел бы иметь там какой-то список, содержащий значения 11 и 12.

Где-то я читал, что в подзапросах может быть только один столбец (нормально для меня в этом случае) и только одна строка (что объясните, что указанный выше запрос не работает для меня). Если это так, как это можно сделать? Или мне действительно нужно выпустить SELECT запросов для каждой строки table_a в моей программе?

Я бы хотел, чтобы это работало с PostgreSQL 9.1 и 9.3.

+0

просто показать ур ожидаемый результат ?? вы хотите получить '11 и 12' в одну строку или в две строки? –

+0

Я хотел бы иметь одну строку, содержащую 'name' =' 'First row'' и' b_ids' что-то вроде '(11, 12)'. – Tobias

+0

Вы хотите string_agg (id, ',') over (partition by a_id) Я думаю –

ответ

3

Вы можете использовать функцию array_agg:

SELECT table_a.name, array_agg(table_b.id) 
FROM table_a 
LEFT OUTER JOIN table_b 
ON table_a.id = table_b.a_id 
GROUP BY table_a.name; 

┌───────────┬───────────┐ 
│ name │ array_agg │ 
├───────────┼───────────┤ 
│ First row │ {11,12} │ 
└───────────┴───────────┘ 
(1 row) 
+0

Спасибо, это работает! Любая специальная причина для 'LEFT OUTER JOIN' вместо подзаголовка? – Tobias

0
select name 
     ,string_agg(b.id::text,',') b_ids 
from table_a join table_b b on table_a.id= b.a_id 
group by name