将具有多个值的水平表转换为聚合垂直表

时间:2012-02-16 12:45:23

标签: php mysql

我正在考虑如何做到这一点,我的大脑很难受。 首先,这是mysql和php。

我有一张表有8列的表

id - user -a1 -a2 -a3 -a4 -a5 -a6
518   96   0   1   2   1   0   0
519  108   0   0   1   1   2   1
520   56   1   0   1   0   1   2

0 = no
1 = yes
2 = n/a

我希望能够选择这些列中的6个,但我希望显示如下:

Question - Yes                     - No      - N/A
   a1       %of all rows with 1     %of 0    %of 2
   a2       %of all rows with 1     %of 0    %of 2
   a3       %of all rows with 1     %of 0    %of 2
   a4       %of all rows with 1     %of 0    %of 2 
   a5       %of all rows with 1     %of 0    %of 2
   a6       %of all rows with 1     %of 0    %of 2

对于%i我认为我会做这样的事情:

$i = 0;
if ($thequestion->a1==1) $i ++;
$num_amount = $i;
$num_total = '25';

$yespercentage = round($num_amount * 100 / $num_total)."%";

非常感谢任何正确方向的帮助/指示。

2 个答案:

答案 0 :(得分:3)

您可以使用GROUP BYaggregate functions针对单个问题执行此操作。然后,您可以使用UNION将6个查询(针对六个问题)组合到单个结果中。通过使用SUM(CASE WHEN ...),您可以分别计算三种情况:是,否,不适用。

它有点长,但我不知道比这更好。它应该输出您需要的表,没有百分比。您可以随意插入百分比计算,这也可以在此SQL中完成:

SELECT 
  "a1" AS question,
  SUM(CASE WHEN a1 = 0 THEN 1 ELSE 0 END) AS no,
  SUM(CASE WHEN a1 = 1 THEN 1 ELSE 0 END) AS yes,
  SUM(CASE WHEN a1 = 2 THEN 1 ELSE 0 END) AS na,
  COUNT(id) AS total
FROM tbl 
UNION ALL
SELECT 
  "a2" AS question,
  SUM(CASE WHEN a2 = 0 THEN 1 ELSE 0 END) AS no,
  SUM(CASE WHEN a2 = 1 THEN 1 ELSE 0 END) AS yes,
  SUM(CASE WHEN a2 = 2 THEN 1 ELSE 0 END) AS na,
  COUNT(id) AS total
FROM tbl 
UNION ALL
SELECT 
  "a3" AS question,
  SUM(CASE WHEN a3 = 0 THEN 1 ELSE 0 END) AS no,
  SUM(CASE WHEN a3 = 1 THEN 1 ELSE 0 END) AS yes,
  SUM(CASE WHEN a3 = 2 THEN 1 ELSE 0 END) AS na,
  COUNT(id) AS total
FROM tbl 
UNION ALL
SELECT 
  "a4" AS question,
  SUM(CASE WHEN a4 = 0 THEN 1 ELSE 0 END) AS no,
  SUM(CASE WHEN a4 = 1 THEN 1 ELSE 0 END) AS yes,
  SUM(CASE WHEN a4 = 2 THEN 1 ELSE 0 END) AS na,
  COUNT(id) AS total
FROM tbl 
UNION ALL
SELECT 
  "a5" AS question,
  SUM(CASE WHEN a5 = 0 THEN 1 ELSE 0 END) AS no,
  SUM(CASE WHEN a5 = 1 THEN 1 ELSE 0 END) AS yes,
  SUM(CASE WHEN a5 = 2 THEN 1 ELSE 0 END) AS na,
  COUNT(id) AS total
FROM tbl 
UNION ALL
SELECT 
  "a6" AS question,
  SUM(CASE WHEN a6 = 0 THEN 1 ELSE 0 END) AS no,
  SUM(CASE WHEN a6 = 1 THEN 1 ELSE 0 END) AS yes,
  SUM(CASE WHEN a6 = 2 THEN 1 ELSE 0 END) AS na,
  COUNT(id) AS total
FROM tbl 

示例百分比:

SELECT
  "a1" AS question,
  (SUM(CASE WHEN a1 = 0 THEN 1 ELSE 0 END) / COUNT(id) * 100) AS no_percentage,
  (SUM(CASE WHEN a1 = 1 THEN 1 ELSE 0 END) / COUNT(id) * 100) AS yes_percentage,
  (SUM(CASE WHEN a1 = 2 THEN 1 ELSE 0 END) / COUNT(id) * 100) AS na_percentage
FROM tbl

所需的PHP打印示例:

<table>
  <thead>
    <tr>
      <td>Question</td>
      <td>Yes %</td>
      <td>No %</td>
      <td>N/A %</td>
    </tr>
  </thead>
  <tbody>
<?php
// given this functions returns the result set as multi-dimensional array
$rows = get_records_sql($thequery);
foreach ($rows as $row) {
    echo '<tr>';
    echo '<td>'.$row->yes_percentage.'%</td>';
    echo '<td>'.$row->yes_percentage.'% </td>';
    echo '<td>'.$row->no_percentage.'% </td>';
    echo '<td>'.$row->na_percentage.'% </td>';
    echo '</tr>';
}
?>
  </tbody>
</table>

答案 1 :(得分:0)

希望这有帮助

SELECT 
       SUM(CASE WHEN a1 = 0 THEN 1 ELSE 0 END) AS a1-NO,
       SUM(CASE WHEN a1 = 1 THEN 1 ELSE 0 END) AS a1-Yes,
       SUM(CASE WHEN a1 = 2 THEN 1 ELSE 0 END) AS a1-N/A,
       ...// similarly for all other columns
FROM table_name