我有2个相关表格:问题和答案
问题
CREATE TABLE questions (
id SERIAL PRIMARY KEY,
title TEXT,
answer_ids INTEGER[]
);
答案
CREATE TABLE answers (
answer_id SERIAL PRIMARY KEY,
question_id INTEGER
REFERENCES questions,
body TEXT
);
当前实施:
当将一行添加到答案表时,我将答案的answer_id
推送到相应行中问题表的answer_ids
数组中。即
如果添加了对answer_id = 5
问题的回答id = 1
。我会做类似
UPDATE questions SET answer_ids = ARRAY_APPEND(answer_ids, 5) WHERE id = 1;
我要实现的目标:
我不一定要寻找一种将答案添加到问题表中的方法,因为我认为这是多余的,那么拥有答案表的意义何在?
我正在寻找一个查询,该查询使我可以提出一个问题,但我希望得到一个answer_ids
本身的数组,而不是得到一个answers
的数组。因此查询将在JSON中返回类似这样的内容:
{ id: 1,
title: 'title of question 1',
answers: [{ answer_id: 1,
question_id: 1,
body: 'body of answer 1'},
{ answer_id: 3,
question_id: 1,
body: 'body of answer 3'}]
}
答案 0 :(得分:3)
可能是这个吗? (here are functions for work with json)
WITH Questions(id, title) as (
select 1, 'title 1' union all
select 2, 'title 2'
),
Answers(answer_id, question_id, body) as (
select 1, 1, 'body of answer 1' union all
select 3, 1, 'body of answer 3' union all
select 4, 2, 'body of answer 4'
)
SELECT json_build_object('id',id, 'title',title, 'answers',
(SELECT json_agg(json_build_object('answer_id',answer_id,'question_id',question_id,'body',body)) FROM Answers WHERE Answers.question_id = Questions.id) )
from Questions
WHERE Questions.id = 1
答案 1 :(得分:1)
为n个答案创建类型。
CREATE TYPE answer_t
AS (answer_id integer,
question_id integer,
body text);
然后将answer_id
与问题横向交叉连接,并使用它们内部连接答案。现在汇总并使用array_agg()
来获得每个问题的答案数组。
SELECT q.*,
array_agg((a.answer_id,
a.question_id,
a.body)::answer_t) answers
FROM questions q
CROSS JOIN LATERAL unnest(q.answer_ids) un(answer_id)
INNER JOIN answers a
ON a.answer_id = un.answer_id
GROUP BY q.id;
但是请注意,您的数据设计太糟糕了,应该修改。引用其他记录的值绝不能放在数组中。如果引用完整性位于数组中,则无法强制执行引用完整性,或者仅使用效率非常低的触发器才能强制执行引用完整性。使用链接表。然后,您也可以将后退引用列退回到question_id
中的列answers
。