一个子查询中的多个列

时间:2013-09-27 15:07:39

标签: mysql

我有点问题。我有这样的数据库布局:

customer
customer_id, name, age, etc...

customer_survey_question
id, category, caption, type

customer_survey_answer
id, customer_id, customer_survey_question_id, answer

我需要像他们一样提出答案:

name, age, etc..., question 1, question 2, question 3, etc...

现在我可以做一个子查询:

SELECT
  `customer`.*,
  (
    SELECT `answer`
    FROM `customer_survey_answer`
    WHERE `customer_survey_answer`.`customer_id`=`customer`.`customer_id`
    AND `id`=1
  ) AS `question_1`,
  (
    SELECT `answer`
    FROM `customer_survey_answer`
    WHERE `customer_survey_answer`.`customer_id`=`customer`.`customer_id`
    AND `id`=2
  ) AS `question_2`,
  ....

但是有14个问题,我需要能够很快完成这项工作并扩展到80多个问题。最好的方法是什么?

4 个答案:

答案 0 :(得分:1)

你不能通过查询本身来做到这一点。

在这里查看一些示例代码:How to merge data from 2 tables with MySQL

您可以使用INNER JOINGROUP_CONCAT,然后重新格式化脚本中的数据(无论是php还是其他语言)

使用JOIN

在这种情况下,这可能会导致每行中过多/无关的数据

SELECT c.*, csa.answer
FROM customers c
INNER JOIN
    customer_survey_answer csa ON csa.`customer_id`=c.`customer_id`
ORDER BY c.customer_id, csa.customer_survey_question_id

使用GROUP_CONCAT

这将输出一个单元格(csv样式)作为答案

SELECT c.*, GROUP_CONCAT(csa.answer) as answers
FROM customers c
INNER JOIN
    customer_survey_answer csa ON csa.`customer_id`=c.`customer_id`
GROUP BY c.customer_id

使用循环

您可能还会考虑在数据库中查找带有答案的客户列表,然后运行第二个查询(针对每个返回的客户)以获得答案。 这可能导致大量查询。

首先查询:

SELECT * FROM customers

第二次查询:

SELECT answer
FROM customer_survey_answer
WHERE customer_id = INSERT_CUSTOMER_ID_HERE}

答案 1 :(得分:0)

您想要转动数据

SELECT class,GROUP_CONCAT(member)
FROM tbl
GROUP BY class;

是基本案例

http://www.artfulsoftware.com/infotree/queries.php#78

答案 2 :(得分:0)

强制DB输出到结果列中是不明智的。

如果您想操作一个唯一的客户,请进行简单的问题查询,然后回答查询以获取所有内容并将其放在DB之外 - 例如在PHP中。

如果您希望客户列表及其答案,请首先进行问题查询,然后使用相应的ID进行“回答x客户”查询,并使用数据库外的散列将它们放在一起。除非你不使用分页作为输出列表,否则它运行良好且快速。)。

哈希可以像这样工作

// suppose we have from database
// $answer_list(id,customer_id,customer_name,question_id,answer)
// $question_list(id,question)

// hash 
$customer_list = array();
$customer_hash = array();
foreach ($answer_list as $answer)
{
  $customer_id = $answer['customer_id'];
  if (!isset($customer_hash[$customer_id]))
  {
    $customer_list[] = $customer_id;
    $customer_hash[$customer_id]['name'] = $answer['customer_name'];
  }
  $customer_hash[$customer_id]['answer_hash'][$answer['question_id']] = $answer;
}


// output
foreach ($customer_list as $customer_id)
{
  echo $customer_hash[$customer_id]['id'];
  echo $customer_hash[$customer_id]['name'];
  foreach ($question_list as $question)
  {
    echo $question['question'];
    echo $customer_hash[$customer_id]['answer_hash'][$question['id]]['answer'];
  }
}

答案 3 :(得分:0)

如果要在单个查询中生成表,可以在查询中使用group by并使用单个INNER JOIN,然后在多个MAX( CASE ... END )表达式中收集值。起初听起来很复杂,但确实可靠(只需为每个所需的列添加另一行):

SELECT name, age,
MAX(CASE WHEN customer_survey_question_id=1 THEN answer END) a1,
MAX(CASE WHEN customer_survey_question_id=2 THEN answer END) a2,
MAX(CASE WHEN customer_survey_question_id=3 THEN answer END) a3,
MAX(CASE WHEN customer_survey_question_id=4 THEN answer END) a4,
MAX(CASE WHEN customer_survey_question_id=5 THEN answer END) a5,
MAX(CASE WHEN customer_survey_question_id=6 THEN answer END) a6,
MAX(CASE WHEN customer_survey_question_id=7 THEN answer END) a7,
MAX(CASE WHEN customer_survey_question_id=8 THEN answer END) a8,
...
FROM customer c INNER JOIN customer_survey_answer s 
                ON s.customer_id=c.customer_id