Как выбрать несколько полей в одной строке? (Баз данных) - PullRequest
7 голосов
/ 23 января 2010

Я задал вопрос вчера об использовании MySQL для подсчета результатов в опросе.

Теперь мой вопрос: если бы у меня была таблица вопросов для опроса, таблица вариантов опроса и таблица ответов пользователей на эти вопросы опроса, как бы я выбрал вопрос опроса вместе со всеми вариантами опроса в этом опросе? тот же запрос?

Таблица вопросов

question_id (int)
question (text)

Таблица выбора

choice_id (int)
question_id (int)
choice_text (varchar)

Таблица ответов

answer_id (int)
question_id (int)
choice_id (int)

Что мне следует выбрать, чтобы получить вопрос об опросе вместе со всеми вариантами этого опроса (известная или неизвестная сумма) в одном запросе? (если возможно, также сделайте математику, найденную в моем другом вопросе, в том же запросе)

Я не настолько продвинут в работе с MySQL.

Спасибо

РЕДАКТИРОВАТЬ: Извините, я имел в виду, что я пытаюсь получить инструкцию SELECT для выбора вопроса и все варианты, соответствующие этому вопросу, в одной строке.

Если я сделаю что-то вроде

SELECT question_id, question, choice_id, choice_text FROM questions LEFT JOIN choices USING(question_id)

Я получаю несколько строк, по одной для каждого choice_id.

Результаты должны быть примерно такими:

question     choice_1  choice_2  choice_3
A or B or C     A          B        C

Математическая часть подсчитывает результаты опроса, и да, choice_id - это PK, если это помогает.

Ответы [ 4 ]

4 голосов
/ 23 января 2010

Чтобы получить вопросы и варианты для каждого вопроса:

SELECT question, choice_text
FROM questions
JOIN choices
ON questions.question_id = choices.question_id

Добавьте LEFT перед JOIN, если вы также хотите, чтобы у вас не было вопросов.

Чтобы получить количество для каждого ответа, вы можете сделать это:

SELECT question, choice_text, COUNT(answers.choice_id)
FROM questions
JOIN choices
    ON questions.question_id = choices.question_id
LEFT JOIN answers
    ON questions.question_id = answers.question_id
    AND choices.choice_id = answers.choice_id
GROUP BY questions.question_id, choices.choice_id
ORDER BY questions.question_id, choices.choice_id

Чтобы получить количество людей, которые выбрали каждый ответ в процентах (на вопрос), используйте следующий запрос:

SELECT question, choice_text, COUNT(answers.choice_id) * 100 / questiontotal
FROM questions
JOIN (
        SELECT questions.question_id, COUNT(answers.choice_id) AS questiontotal
        FROM questions
        LEFT JOIN answers ON questions.question_id = answers.question_id
        GROUP BY questions.question_id
    ) AS answercounts
    ON questions.question_id = answercounts.question_id
JOIN choices ON questions.question_id = choices.question_id
LEFT JOIN answers
    ON questions.question_id = answers.question_id
    AND choices.choice_id = answers.choice_id
GROUP BY questions.question_id, choices.choice_id
ORDER BY questions.question_id, choices.choice_id;

Вот тестовые данные, которые я использовал:

CREATE TABLE questions (question_id int, question nvarchar(100));
INSERT INTO questions (question_id, question) VALUES
(1, 'Foo?'),
(2, 'Bar?');

CREATE TABLE choices (choice_id int, question_id int, choice_text nvarchar(100));
INSERT INTO choices (choice_id, question_id, choice_text) VALUES
(1, 1, 'Foo1'),
(2, 1, 'Foo2'),
(3, 1, 'Foo3'),
(4, 2, 'Bar1'),
(5, 2, 'Bar2');

CREATE TABLE answers (answer_id int, question_id int, choice_id int);
INSERT INTO answers (answer_id, question_id, choice_id) VALUES
(1, 1, 1),
(2, 1, 1),
(3, 1, 3),
(4, 2, 4),
(4, 2, 5);

И вывод, который я получаю с последним запросом по этим данным:

'Foo?', 'Foo1', 66.6667
'Foo?', 'Foo2', 0.0000
'Foo?', 'Foo3', 33.3333
'Bar?', 'Bar1', 50.0000
'Bar?', 'Bar2', 50.0000

В обновлении своего вопроса вы говорите, что хотите вернуть все значения для одного вопроса в одной строке. Я бы порекомендовал вам , а не , попытаться сделать это, и вместо этого использовать метод, который я дал вам выше. Если вам нужно представить данные в одну строку конечному пользователю, это можно сделать с помощью PHP.

3 голосов
/ 23 января 2010

Я бы предложил ответ Марка Байерса, хотя теоретически, если они вам нужны «все в один ряд», просто для просмотра, а не как часть процедуры PHP, которую вы можете сделать.

SELECT question, GROUP_CONCAT(choice_text) as choice_texts
FROM questions
JOIN choices
ON questions.question_id = choices.question_id
GROUP BY question;

Вывод будет

'Foo?', 'Foo1,Foo2,Foo3'
'Bar?', 'Bar1,Bar2'

Примечание. 'Foo1, Foo2, Foo3' будут возвращены как один столбец, а не как три столбца, а GROUP_CONCAT имеет по умолчанию максимум 1024 символа в выводе, хотя его можно увеличить. Не рекомендуется, если результаты могут быть большими

2 голосов
/ 23 января 2010

Обратите внимание, что таблица ответов, вероятно, не нуждается в столбце QuestionID.

Это даст вам текст вопроса, текст выбора и количество ответов на выбор.

SELECT Questions.question, Choices.choice_text, Count(Answers.*) AS N
FROM Questions INNER JOIN Choices ON Questions.question_id = Choices.question_id
     LEFT JOIN Answers ON Choices.choice_id = Answers.choice_id
GROUP BY Questions.question_id, Choices.choice_id

Редактировать: если вы не очень хорошо разбираетесь в SQL, вероятно, лучше всего забыть о части «все в одну строку» - если количество вариантов ответа на вопрос не только известно, но и постоянно, и даже в этом случае это не легко. Это действительно проблема отображения, поэтому устраните ее, когда отобразите результаты.

0 голосов
/ 23 января 2010
SELECT questions.question_id, questions.question, choices.choice_id, choices.question_id
FROM questions, choices 
WHERE questions.question_id = choices.question_id 
AND questions.question_id = "Something"

Должен работать, думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...