I have two tables: question and answer.
Here is a simplified version of the question table's schema:
question_id integer PRIMARY KEY
question_title varchar(250)
answers_id SERIAL UNIQUE
Here is a simplified version of the answer table's schema:
answer_id integer REFERENCES question (answers_id)
answer_text varchar(500)
is_top_answer boolean
I would like to accomplish three tasks in a single query:
I have populated the question and answer tables with the following SQL statements:
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');
If I were to query the question table with a parameter that represents a question_id held in the question table, I would expect the following row as a result:
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 |
I have tried to use a subquery SELECT statement, which attempts to satisfy tasks 2 and 3 of the query by returning all the row from the answer table where answer_id matches the answers_id of the question table's row ordered by ascending values of the is_top_answer, within a LEFT JOIN statement, but I have not had success because the postgres complains with a "subquery must return only one column" error. Here is the query:
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
I have also tried this query:
select * from question inner join answer on question.answers_id = answer.answer_id
where question.question_id = 1
order by answer.is_top_answer;
The result of this query is three rows:
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
Each row has a copy of a row from the question and answer tables. I am not looking for three rows, I am trying to create a query that returns one row that is a combination of one row from the question table and multiple rows from the answer table.
Any advice about accomplishing the three tasks in a single query would be greatly appreciated. Thanks
does this work? (havent tested it)
select * from question inner join answer on
questions.answers_id=answer.answer_id where question.question_id = $1
this will bring all of the answers. you can not get both all the ansers and the best answers. it makes no sence. if you get all of them you will get the best answer as well. maybe you can do
select * from question inner join answer on
questions.answers_id=answer.answer_id where question.question_id = $1
order by asnwer.is_top_answer
in order to get the top answer first on the list
If you want one row, then use aggregation:
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;
The data structure in your question seems messed up. Normally, each question would have a unique auto-incremented primary key called question_id
. Each answer would have a unique auto-incremented primary key called answer_id
. Each answer would also have a link back to the question via a field called question_id
. However, this answer follows the naming conventions in the question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.