【问题标题】:HTML table from MySQL with most recent and unique values来自 MySQL 的具有最新和唯一值的 HTML 表
【发布时间】:2013-03-27 19:45:02
【问题描述】:

不确定要搜索什么,因此这可能是一个重复的问题。我有一个 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的版本?

【问题讨论】:

  • 此表中是否有任何类型的主键字段(可能是自动增量)?
  • 是的,有一个 id 字段可以自动递增。更新问题...
  • 如果安装日期是一个 unix 时间戳,你就不需要一个自动递增的主键(即使我身体里的每一根骨头都告诉我你应该有一个),你可以按 install_date 降序排序。但是,设置一个主键和一个简单的选择不同应该可以工作......

标签: php mysql database codeigniter


【解决方案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;

我的表格数据有这些值:

------ ---------------- --------------- -------------- ---- --------- |编号 |计算机名 |软件名称 |软件版本 |安装日期 | --------------- ------ --------------- -------------- ---- --------- | 1 |电脑a |软件 x | 1.1 版 | 2013-03-27 15:58:17 | | 2 |电脑a |软件 x |版本 1.0 | 2013-03-27 15:58:20 | | 3 |电脑a |软件z | 1.3 版 | 2013-03-27 15:58:24 | | 4 |电脑b |软件z | 1.4 版 | 2013-03-27 15:58:30 | | 5 |电脑b |软件z | 1.2 版 | 2013-03-27 15:58:45 | | 6 |电脑c |软件 x | 1.5 版 | 2013-03-27 15:58:51 | | 7 |电脑c |软件y | 1.7 版 | 2013-03-27 15:58:58 | --------------- ------ --------------- -------------- ---- ---------

这是我的输出:

------------ ------------ ------------------ |电脑 |软件 |软件版本 | ------------ ------------ ------------------ |电脑a |软件 x | 1.1 版 | |电脑a |软件y | | |电脑a |软件z | 1.3 版 | |电脑b |软件 x | | |电脑b |软件y | | |电脑b |软件z | 1.4 版 | |电脑c |软件 x | 1.5 版 | |电脑c |软件y | 1.7 版 | |电脑c |软件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 代码工作正常!祝你好运!

【讨论】:

  • 看起来不错,但computer b 应该有ver 1.2 作为software z 的安装版本,因为它是在ver 1.4 之后安装的。有什么办法纠正吗?
  • @codybuell 我以为你想要最高的软件版本,而不是最后安装的版本...我会尝试修改...
【解决方案2】:

这样的东西应该可以工作(比使用 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

【讨论】:

    猜你喜欢
    • 2014-07-01
    • 2018-08-12
    • 1970-01-01
    • 2012-11-10
    • 2020-08-04
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    相关资源
    最近更新 更多