查询此问题的最佳方式是什么?

发布于 2024-11-19 12:58:21 字数 439 浏览 0 评论 0原文

我有看起来像这样的表:

questions:
id description
1   Q1
2   Q2

answers:
id question_id x y description
1     1        1 2   A1
2     1        3 4   A2
3     2        5 6   A3
4     2        7 8   A4

我想要得到的是一个可以输出以下内容的查询:

Q1 A1 1,2 A2 3,4
Q2 A3 5,6 A4 7,8

我已经花了好几天的时间试图弄清楚这一点。我正在 PHP 和 MySQL 中完成此操作,因此如果有人可以提供一些线索,那就太好了。

编辑:我忘了提及我也使用 CodeIgniter 来实现此目的。所以,这可能有助于找到答案。

I have tables that look like this:

questions:
id description
1   Q1
2   Q2

answers:
id question_id x y description
1     1        1 2   A1
2     1        3 4   A2
3     2        5 6   A3
4     2        7 8   A4

What I want to get is a query that can output this:

Q1 A1 1,2 A2 3,4
Q2 A3 5,6 A4 7,8

I've been pulling my hair for days now trying to figure this out. I'm doing this in PHP and MySQL so if anyone can shed some light out there, that'd be really great.

EDIT: I forgot to mention that I'm using CodeIgniter for this, too. So, that might help with the answers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柠檬心 2024-11-26 12:58:21

考虑到每个问题可能有随机数量的答案,您无法设计返回固定数量列的查询。您必须为每个问题返回一个结果,然后在代码中进行一些解析。

GROUP_CONCAT 函数对于解决此类问题很有帮助:

SELECT q.description, GROUP_CONCAT(
    CONCAT(a.description,' ',a.x,',',a.y) ORDER BY a.id
    SEPARATOR ' '
    ) AS answers
FROM questions q
  JOIN answers a ON a.question_id = q.id
GROUP BY q.description;

将返回

+-------------+---------------+
| description | answers       |
+-------------+---------------+
| Q1          | A1 1,2 A2 3,4 |
| Q2          | A3 5,6 A4 7,8 |
+-------------+---------------+
2 rows in set (0.00 sec)

您可以根据您想要在代码中解析结果的任何内容来更改 SEPARATOR 值。您可以使用 GROUP_CONCAT 函数的 ORDER BY 子句对每个答案的返回结果中的答案进行排序(这里我按答案 id 排序)。

编辑:如果您确定每个问题的答案永远不会超过 4 个,您可以发出以下查询,将每个答案放入其自己的列中:

SELECT description,
  REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

将返回

+-------------+----------+----------+----------+----------+
| description | answer_1 | answer_2 | answer_3 | answer_4 |
+-------------+----------+----------+----------+----------+
| Q1          | A1 1,2   | A2 3,4   |          |          |
| Q2          | A3 5,6   | A4 7,8   | A5 9,10  |          |
+-------------+----------+----------+----------+----------+
2 rows in set (0.00 sec)

我添加了第二个问题的答案为了说明。

, 1), LENGTH(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 1 - 1)) + 1), '

将返回


我添加了第二个问题的答案为了说明。

, '') answer_1, REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 2), LENGTH(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 2 - 1)) + 1), '

将返回


我添加了第二个问题的答案为了说明。

, '') answer_2, REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 3), LENGTH(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 3 - 1)) + 1), '

将返回


我添加了第二个问题的答案为了说明。

, '') answer_3, REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 4), LENGTH(SUBSTRING_INDEX(answers, '

将返回


我添加了第二个问题的答案为了说明。

, 4 - 1)) + 1), '

将返回


我添加了第二个问题的答案为了说明。

, '') answer_4 FROM ( SELECT q.description, GROUP_CONCAT( CONCAT(a.description,' ',a.x,',',a.y) ORDER BY a.id SEPARATOR '

将返回


我添加了第二个问题的答案为了说明。

) AS answers FROM questions q JOIN answers a ON a.question_id = q.id GROUP BY q.description ) t;

将返回

我添加了第二个问题的答案为了说明。

Considering that there might be a random number of answers per question, you cannot design a query that will return a fixed number of columns. You have to return a single result per question and then do a little bit of parsing in your code.

The GROUP_CONCAT function can be helpful for this kind of problem:

SELECT q.description, GROUP_CONCAT(
    CONCAT(a.description,' ',a.x,',',a.y) ORDER BY a.id
    SEPARATOR ' '
    ) AS answers
FROM questions q
  JOIN answers a ON a.question_id = q.id
GROUP BY q.description;

Will return

+-------------+---------------+
| description | answers       |
+-------------+---------------+
| Q1          | A1 1,2 A2 3,4 |
| Q2          | A3 5,6 A4 7,8 |
+-------------+---------------+
2 rows in set (0.00 sec)

You can change the SEPARATOR value by whatever you want to parse the result in your code. You can use the ORDER BY clause of the GROUP_CONCAT function to order the answers in the returned result for each answer (here I ordered by answer id).

Edit: If you are sure that there will never be more than 4 answers per question, you can issue the following query to put each answer in its own column:

SELECT description,
  REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

Will return

+-------------+----------+----------+----------+----------+
| description | answer_1 | answer_2 | answer_3 | answer_4 |
+-------------+----------+----------+----------+----------+
| Q1          | A1 1,2   | A2 3,4   |          |          |
| Q2          | A3 5,6   | A4 7,8   | A5 9,10  |          |
+-------------+----------+----------+----------+----------+
2 rows in set (0.00 sec)

I added an answer to the second question for the illustration.

, 1), LENGTH(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 1 - 1)) + 1), '

Will return


I added an answer to the second question for the illustration.

, '') answer_1, REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 2), LENGTH(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 2 - 1)) + 1), '

Will return


I added an answer to the second question for the illustration.

, '') answer_2, REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 3), LENGTH(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 3 - 1)) + 1), '

Will return


I added an answer to the second question for the illustration.

, '') answer_3, REPLACE(SUBSTRING(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 4), LENGTH(SUBSTRING_INDEX(answers, '

Will return


I added an answer to the second question for the illustration.

, 4 - 1)) + 1), '

Will return


I added an answer to the second question for the illustration.

, '') answer_4 FROM ( SELECT q.description, GROUP_CONCAT( CONCAT(a.description,' ',a.x,',',a.y) ORDER BY a.id SEPARATOR '

Will return


I added an answer to the second question for the illustration.

) AS answers FROM questions q JOIN answers a ON a.question_id = q.id GROUP BY q.description ) t;

Will return

I added an answer to the second question for the illustration.

萤火眠眠 2024-11-26 12:58:21

从答案中选择 * ORDER BY Question_id

$question_id = 0;
$print_ln = null;
foreach ($result as $row) {
  if ($question_id != $row['question_id']) { 
     echo "<br>";
     $question_id = $row['question_id'];
     $print_ln = "Q" . $row['question_id'] . " " . $row['description'] . " " . $row['x'] . "," . $row['y'];
  } else { 
     $print_ln = $print_ln . " " . $row['description'] . " " . $row['x'] . "," . $row['y'];
  }
  echo $print_ln;
 }

请注意,此代码仍然需要一些工作......它可以让您了解如何做到这一点。

select * from answers ORDER BY question_id

$question_id = 0;
$print_ln = null;
foreach ($result as $row) {
  if ($question_id != $row['question_id']) { 
     echo "<br>";
     $question_id = $row['question_id'];
     $print_ln = "Q" . $row['question_id'] . " " . $row['description'] . " " . $row['x'] . "," . $row['y'];
  } else { 
     $print_ln = $print_ln . " " . $row['description'] . " " . $row['x'] . "," . $row['y'];
  }
  echo $print_ln;
 }

Note, this code still needs a bit of work ... its to give you an idea on how to do it.

小梨窩很甜 2024-11-26 12:58:21

此查询:

SELECT 
      q.id
    , q.description
    , a.description
    , CONCAT(a.x, ',', a.y)
FROM questions AS q
    JOIN answers AS a
        ON a.question_id = q.id
ORDER BY q.id
       , a.id

将显示:

| 1 | Q1 | A1 | 1,2 |
| 1 | Q1 | A2 | 3,4 |
| 2 | Q2 | A3 | 5,6 |
| 2 | Q2 | A4 | 7,8 |

您所描述的最终结果称为透视,这在 MySQL 中并不容易,并且取决于您拥有的数据。例如,如果一个问题有超过 2 个答案,应该显示什么?

为什么结果会是这样的:

| Q1 | A1 | 1,2 | A2 | 3,4 | 
| Q2 | A3 | 5,6 | A4 | 7,8 |

而不是那样?:

| Q1 | A1 | 1,2 | A2 | 3,4 | 
| Q2 | A4 | 7,8 | A3 | 5,6 | 

无论如何,对于每个问题最多 4 个答案并按 answers.id 进行排序,这是可行的。最好使用前面的查询并在 PHP 中进行旋转,这样您就可以毫无问题地处理可变数量的列:

SELECT 
      q.id
    , q.description
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 0,1
      ) AS answer1
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 0,1
      ) AS xy1
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 1,1
      ) AS answer2
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 1,1
      ) AS xy2
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 2,1
      ) AS answer3
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 2,1
      ) AS xy3
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 3,1
      ) AS answer4
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 3,1
      ) AS xy4
FROM questions AS q
ORDER BY q.id  

This query:

SELECT 
      q.id
    , q.description
    , a.description
    , CONCAT(a.x, ',', a.y)
FROM questions AS q
    JOIN answers AS a
        ON a.question_id = q.id
ORDER BY q.id
       , a.id

will show:

| 1 | Q1 | A1 | 1,2 |
| 1 | Q1 | A2 | 3,4 |
| 2 | Q2 | A3 | 5,6 |
| 2 | Q2 | A4 | 7,8 |

What you describe as final result is called pivoting and it's not easy in MySQL and depends on the data you have. For example, what should be shown if for a question, there are more than 2 answers?

And why will the result be this:

| Q1 | A1 | 1,2 | A2 | 3,4 | 
| Q2 | A3 | 5,6 | A4 | 7,8 |

and not like that?:

| Q1 | A1 | 1,2 | A2 | 3,4 | 
| Q2 | A4 | 7,8 | A3 | 5,6 | 

Anyway, for maximum of 4 answers per questions and ordering per answers.id, this will work. It may be best though to use the previous query and do the pivoting in PHP, where you can handle variable number of columns without problem:

SELECT 
      q.id
    , q.description
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 0,1
      ) AS answer1
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 0,1
      ) AS xy1
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 1,1
      ) AS answer2
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 1,1
      ) AS xy2
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 2,1
      ) AS answer3
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 2,1
      ) AS xy3
    , ( SELECT a.description
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 3,1
      ) AS answer4
    , ( SELECT CONCAT(a.x, ',', a.y)
        FROM answers AS a
        WHERE a.question_id = q.id
        ORDER BY a.id  LIMIT 3,1
      ) AS xy4
FROM questions AS q
ORDER BY q.id  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文