在将一个表连接到多个表之前对行进行排序?

时间:2015-06-07 14:39:22

标签: sql postgresql

我有两张桌子:问答。

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

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

以下是答案表格架构的简化版本:

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              |
    

    我尝试使用子查询SELECT语句,该语句尝试通过返回answer表中的所有行来满足查询的任务2和3,其中answer_id匹配通过提升排序的问题表的行的answers_id在LEFT JOIN语句中is_top_answer的值,但是我没有成功,因为postgres抱怨"子查询必须只返回一列"错误。这是查询:

        SELECT (q.question_id, q.question_title), 
            (SELECT answer_id, answer_text FROM answer 
                WHERE answer_id = q.answers_id 
                ORDER BY is_top_answer ASC) 
        FROM question q 
        RIGHT JOIN answer a ON a.answer_id = q.answers_id 
        WHERE q.question_id = $1
    

    我也试过这个问题:

        select * from question inner join answer on question.answers_id = answer.answer_id 
        where question.question_id = 1 
        order by answer.is_top_answer;
    

    此查询的结果是三行:

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

    每行都有问答表中的一行副本。我不是在寻找三行,我正在尝试创建一个返回一行的查询,该行是来自问题表的一行和来自答案表的多行的组合。

    任何关于在单个查询中完成三个任务的建议都将不胜感激。感谢

2 个答案:

答案 0 :(得分:0)

这有用吗? (没有测试过它)

select * from question inner join answer on 
    questions.answers_id=answer.answer_id where question.question_id = $1

这将带来所有答案。你无法得到所有的激光和最好的答案。它没有任何意义。如果你得到所有这些,你也会得到最好的答案。也许你可以做到

select * from question inner join answer on 
    questions.answers_id=answer.answer_id where question.question_id = $1
    order by asnwer.is_top_answer

为了在列表中首先得到最佳答案

答案 1 :(得分:0)

如果您想要一行,请使用聚合:

select q.*,
       string_agg(answer_text, '|' order by is_top_answer desc) as answers
from question q inner join
     answer a 
     on q.answers_id = a.answer_id
where q.question_id = $1;

您问题中的数据结构似乎搞砸了。通常,每个问题都有一个名为question_id的唯一自动递增主键。每个答案都有一个名为answer_id的唯一自动递增主键。每个答案还会通过名为question_id的字段返回问题的链接。但是,这个答案遵循问题中的命名惯例。