【问题标题】:How to select multiple fields in the same row? (MySQL)如何在同一行中选择多个字段? (MySQL)
【发布时间】:2011-01-08 10:16:54
【问题描述】:

asked a question yesterday 关于使用 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,如果有帮助的话。

【问题讨论】:

  • 您只是想要选择,还是想要数量?你的“其他问题”是什么?你想做什么“数学”?
  • 您不是在寻找有关正确答案的任何信息吗?只是问题/选择的可能性?
  • @Evan:这是一项调查,不是测试——没有正确答案。
  • 您的数据库设计可能未标准化。你的choice_id是PK吗?如果是这样,如果答案表中的question_id与choice_id的question_id不匹配会怎样?
  • 你不能那样做。至少,您将无法使用 php 获取它(您实际上可以执行 UNION() 但仍然无法正确获取它)。你可以做的是选择问题,所有选项都有正确的答案,然后循环运行。多个问题,ofc。

标签: php mysql select


【解决方案1】:

要获得每个问题的问题和选项:

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

如果您还想要没有选择的问题,请在 JOIN 之前添加 LEFT。

要获得每个答案的计数,您可以这样做:

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 来完成。

【讨论】:

    【解决方案2】:

    我会建议 Mark Byers 的答案,但理论上如果您需要它们“全部放在一行中”只是为了查看目的,而不是作为 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 个字符,尽管它可以增加。如果结果可能很大,不建议这样做

    【讨论】:

      【解决方案3】:

      请注意,Answers 表可能不需要 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,否则最好忘记“全部一行”部分 - 除非每个问题的选择数量不仅是已知的,而且是恒定的,即使在这种情况下也是如此,不容易。确实是显示问题,所以在显示结果的时候处理一下。

      【讨论】:

      • 我希望我能再给一个 +1 来指出不必要的 QuestionID 列。
      • 不幸的是,您的查询似乎对我不起作用。我得到'您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 '*) AS N FROM Questions INNER JOIN Choices ON Questions.question_id = Choices.q' 附近使用正确的语法
      • 这可能是 MySQL 和其他 SQL 服务器之间的语法差异:尝试不带“INNER”一词。 (我的经验就是使用 MS SQL Server。)
      【解决方案4】:
      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"
      

      我认为应该可以。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-22
        相关资源
        最近更新 更多