将可变数量的行合并为一行?

时间:2015-06-08 03:10:00

标签: sql database postgresql

我有两张桌子:问答。

以下是问题表架构的简化版本:

question_id      integer PRIMARY KEY
question_title   varchar(250)
answers_id       SERIAL UNIQUE

以下是 answer 表架构的简化版本:

answer_id        integer REFERENCES question (answers_id)
answer_text      varchar(500)
is_top_answer    boolean

我想在一个查询中完成三项任务:

  1. 根据包含question_id的参数从问题表中选择一行。
  2. 从答案表中加入完全一行行,并在查询的第1步中从问题表中检索到该行,其中答案表中的行满足以下两个条件:1。 is_top_answer为true且2. answer_id等于查询步骤1中从问题表中检索到的行的answers_id。
  3. 从答案表中加入可变数量行,并在查询的第1步中从问题表中检索到该行,其中答案表的answer_id与从问题表中检索到的行的answers_id相匹配在查询的第1步中。
  4. 我已使用以下SQL语句填充问题和答案表:

    insert into question values (1, 'Where is the best sushi restaurant?', 10);
    insert into answer values (10, 'In California', 'false');
    insert into answer values (10, 'In Seattle', 'true');
    insert into answer values (10, 'In New York', 'false');
    

    如果我使用表示问题表中保存的question_id的参数查询问题表,我希望结果是以下单行:

     question_id |           question_title            | answers_id |   answer_text | is_top_answer  |   answer_text | is_top_answer  |   answer_text | is_top_answer  |
    -------------+-------------------------------------+------------+---------------+----------------+---------------+----------------+---------------+----------------+
               1 | Where is the best sushi restaurant? |         10 | In Seattle    | f              | In California | f              | In New York   | f              |
    

    有没有人对完成此查询有任何建议?

1 个答案:

答案 0 :(得分:0)

SELECT 
* 
FROM question 
INNER JOIN answer on question.answers_id = answer.answer_id
WHERE question_id = 1   

这是您需要的基本查询。之后你必须使用crosstab,但由于你有无限数量的答案行,因此非常困难。详细介绍了此SO帖子Dynamic alternative to pivot with CASE and GROUP BY

另一种方法是使用array_agg函数,但结果与您需要的结果不一样

SELECT 
    question_id, array_agg(question_title) AS 'questionlist', array_agg(answers_id || '##' || answer_text || '##' || is_top_answer) AS 'answerlist'
FROM question 
INNER JOIN answer on question.answers_id = answer.answer_id
WHERE question_id = 1  
GROUP BY question_id    

之后你必须在服务器端代码中分割questionlistanswerlist