繁体   English   中英

一个子查询中有多个列

[英]Multiple columns in one subquery

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

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多个问题。 最好的方法是什么?

您本身无法通过查询来执行此操作。

在此处查看一些示例代码: 如何使用MySQL合并2个表中的数据

您可以使用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}

您想要透视数据

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

是基本情况

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

强迫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'];
  }
}

如果要在单个查询中生成表,则可以在具有单个INNER JOIN的查询上使用group by ,然后在多个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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM