来自MySQL的HTML表格,包含最新且唯一的值

时间:2013-03-27 19:45:02

标签: php mysql database codeigniter

不确定要搜索的内容,因此这可能是一个重复的问题。我有一个mysql数据库,其中包含一个名为software的表。软件表由以下字段组成:

id (auto_increment)
computer_name
software_name
software_version
install_date

每次安装,升级或恢复到以前版本的软件时,都会在表格中添加一个新条目。

我正在尝试使用php构建一个表格,如下所示:

.---------------------------------------------------.
|            | software x | software y | software z |
|---------------------------------------------------|
| computer a | ver 1.0    |            | ver 1.2    |
|---------------------------------------------------|
| computer b |            | ver 2.1    |            |
|---------------------------------------------------|
| computer c | ver 1.3    | ver 1.1    |            |
'---------------------------------------------------'

来自这样的数据:

computer_name  |  software_name  |  software_version  |  install_date
----------------------------------------------------------------------
computer a     |  software x     |  ver 1.1           |  [10 days ago]
computer a     |  software x     |  ver 1.0           |  [2 days ago]
computer a     |  software z     |  ver 1.1           |  [20 days ago]
computer a     |  software z     |  ver 1.2           |  [5 days ago]

install_date将是一个实际日期,为了方便而投入[X天前]。

该表将显示每台计算机上安装的每个软件的最新版本,每个唯一的计算机条目只有一行,每个唯一的软件条目只有一列。

这可能与单个MySQL表有关吗?实现这一目标的最佳方法是什么?我正在使用PHP和MySQL与codeigniter。

更新

通过查看可能的重复问题,我能够准备此查询:

SET @sql = NULL;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(IF(software_name = ''',
      software_name,
      ''', software_version, NULL)) AS ',
      replace(software_name, ' ', '_')
    )
  ) INTO @sql 
FROM 
  software;

SET @sql = CONCAT('SELECT computer_name, ', @sql, ' FROM software GROUP BY computer_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

以我正在寻找的格式生成结果,但是它没有获得最新版本install_date的版本,而是找到最大版本号。如何修改上述内容以获取具有最新关联install_date的版本?

2 个答案:

答案 0 :(得分:1)

努力工作但我得到了一个可以达到结果的查询!

您在数据库方面需要的是像CROSS JOIN那样能够针对所有不同的软件列出所有不同的计算机,然后过滤所需的software_version

我用这个查询做到了:

SELECT 
  b.computer_name, 
  a.software_name, 
  MAX(IF(b.software_name = a.software_name AND b.id = a.id, a.software_version, '')) AS software_version 
FROM 
  software AS a, 
  software AS b 
GROUP BY 
  b.computer_name, 
  a.software_name 
ORDER BY 
  b.computer_name ASC, 
  a.software_name ASC, 
  software_version DESC;

我的表数据有以下值:

 ------ --------------- --------------- ------------------ --------------------- 
| id   | computer_name | software_name | software_version | install_date        |
 --------------- ------ --------------- ------------------ --------------------- 
|    1 | computer a    | software x    | ver 1.1          | 2013-03-27 15:58:17 |
|    2 | computer a    | software x    | ver 1.0          | 2013-03-27 15:58:20 |
|    3 | computer a    | software z    | ver 1.3          | 2013-03-27 15:58:24 |
|    4 | computer b    | software z    | ver 1.4          | 2013-03-27 15:58:30 |
|    5 | computer b    | software z    | ver 1.2          | 2013-03-27 15:58:45 |
|    6 | computer c    | software x    | ver 1.5          | 2013-03-27 15:58:51 |
|    7 | computer c    | software y    | ver 1.7          | 2013-03-27 15:58:58 |
 --------------- ------ --------------- ------------------ --------------------- 

这是我的输出:

 ------------ ------------ ------------------ 
| computer   | software   | software_version |
 ------------ ------------ ------------------ 
| computer a | software x | ver 1.1          |
| computer a | software y |                  |
| computer a | software z | ver 1.3          |
| computer b | software x |                  |
| computer b | software y |                  |
| computer b | software z | ver 1.4          |
| computer c | software x | ver 1.5          |
| computer c | software y | ver 1.7          |
| computer c | software z |                  |
 ------------ ------------ ------------------ 

在你的PHP代码中,你应该做这样的事情(因为我知道纯PHP - 我没有测试下面的PHP代码,它不是代码的最佳方式...但我认为它会工作,它是基于在我的查询输出上):

<?php
  $sql = 'SELECT ...';  // put the query here
  $result = mysql_query($sql);

  if( $result and mysql_num_rows($result))
  {
    $num_rows = mysql_num_rows($result);

    $versions = array();
    while ($row = mysql_fetch_assoc($result))
      $versions[] = $row;

    // Here we'll count how much softwares we have 
    $software_count = -1;
    $first_computer = $versions[0]['computer_name'];

    while( $versions[++$software_count]['computer_name'] == $first_computer );

    echo "<table>". 
           "<thead>". 
             "<tr>". 
               "<th></th>";

    // Here we'll print the softwares names as our table headers
    for($i = 0; $i < $software_count; $i++)
      echo "<th>". $versions[$i]['software_name'] . "</th>";

    echo     "</tr>". 
           "</thead>". 
           "<tbody>";

    // Here we'll print the data
    while($num_rows)
    {
      echo   "<tr>". 
               "<td style='font-weight: bold;'>". 
                 $versions[$i]["computer_name"] .
               "</td>";

      for($i = 0; $i < $software_count; $i++)
        echo   "<td>". $versions[$i]["software_version"] . "</td>";

      echo   "</tr>";

      $num_rows -= $software_count;
    }

    echo   "</tbody>".  
         "</table>";

  mysql_free_result($result);

?>

一些工作,但我希望它可以帮助你,我希望我的PHP代码工作正常!祝你好运!

答案 1 :(得分:0)

这样的东西应该有效(比使用distinct要快得多)。

select computer_name,software_name,software_version,install_date from table group by software_name order by computer_name,install_date DESC

这样您仍然可以在每台计算机上显示所有软件。

如果您想限制每个计算机上安装的最新软件的条目,您可以使用:

select computer_name,software_name,software_version,install_date from table group by computer_name,software_name order by computer_name,install_date DESC