加入MySQL表和计算计数 - 用PHP输出

时间:2011-04-29 22:57:59

标签: php mysql select join subquery

我正在尝试在繁忙的公共计算机实验室中查询可用计算机的MySQL数据库。我有两个表,COMPUTERS和COMPUSE。每次用户登录或注销计算机时,都会更新COMPUSE表。当logofftime为null时,计算机正在使用中。在此示例中,计算机1,2,3和8正在使用中。可以使用计算机4,5,6,7,9,10。

|-----------------------|-----------------------|----------|-----------|
|       logontime       |       logofftime      |   recID  | compname  |
|-----------------------|-----------------------|----------|-----------|
|  2011-05-13 13:45:16  |             <<null>>  |  310052  |  Comp001  |
|  2011-05-13 13:35:18  |  2011-05-13 13:39:37  |  310043  |  Comp001  |
|  2011-05-13 12:12:09  |  2011-05-13 12:33:37  |  309979  |  Comp001  |
|  2011-05-13 13:00:57  |             <<null>>  |  310018  |  Comp002  |
|  2011-05-13 11:30:13  |  2011-05-13 12:58:15  |  309940  |  Comp002  |
|  2011-05-13 09:36:15  |  2011-05-13 09:47:22  |  309850  |  Comp002  |
|  2011-05-13 09:25:29  |             <<null>>  |  309840  |  Comp003  |
|  2011-05-13 08:45:38  |  2011-05-13 09:24:03  |  309793  |  Comp003  |
|  2011-05-12 22:39:58  |  2011-05-13 00:36:31  |  309640  |  Comp003  |
|  2011-05-13 12:06:22  |  2011-05-13 12:50:23  |  309972  |  Comp004  |
|  2011-05-13 11:10:16  |  2011-05-13 12:01:16  |  309915  |  Comp004  |
|  2011-05-13 07:17:18  |  2011-05-13 09:42:10  |  309731  |  Comp004  |
|  2011-05-13 11:51:38  |  2011-05-13 12:15:35  |  309959  |  Comp005  |
|  2011-05-13 08:55:14  |  2011-05-13 09:47:48  |  309807  |  Comp005  |
|  2011-05-12 18:15:05  |  2011-05-12 18:15:16  |  309502  |  Comp005  |
|  2011-05-13 12:08:40  |  2011-05-13 13:16:41  |  309974  |  Comp006  |
|  2011-05-13 11:29:09  |  2011-05-13 12:05:56  |  309939  |  Comp006  |
|  2011-05-13 11:10:41  |  2011-05-13 11:19:14  |  309916  |  Comp006  |
|  2011-05-13 10:45:27  |  2011-05-13 11:16:44  |  309896  |  Comp007  |
|  2011-05-13 09:21:42  |  2011-05-13 09:55:48  |  309839  |  Comp007  |
|  2011-05-13 08:23:33  |  2011-05-13 09:14:24  |  309770  |  Comp007  |
|  2011-05-13 13:54:12  |             <<null>>  |  310058  |  Comp008  |
|  2011-05-13 13:38:53  |  2011-05-13 13:39:23  |  310045  |  Comp008  |
|  2011-05-13 10:13:23  |  2011-05-13 13:26:51  |  309878  |  Comp008  |
|  2011-05-13 12:16:06  |  2011-05-13 13:26:21  |  309984  |  Comp009  |
|  2011-05-13 10:13:09  |  2011-05-13 12:15:13  |  309877  |  Comp009  |
|  2011-05-13 08:23:22  |  2011-05-13 10:07:08  |  309769  |  Comp009  |
|  2011-05-13 13:45:51  |  2011-05-13 13:47:11  |  310053  |  Comp010  |
|  2011-05-13 11:18:12  |  2011-05-13 13:19:59  |  309925  |  Comp010  |
|  2011-05-13 07:28:50  |  2011-05-13 09:50:09  |  309737  |  Comp010  |
|-----------------------|-----------------------|----------|-----------|

此数据需要与表格连接,该表格指示计算机所在建筑物的哪个楼层。该表看起来与此类似:

|--------|-----------|-------------|
| compID | compname  |   LOCATION  |
|--------|-----------|-------------|
|    95  |  Comp001  |  1st Floor  |
|    96  |  Comp002  |  1st Floor  |
|    97  |  Comp003  |  1st Floor  |
|    98  |  Comp004  |  1st Floor  |
|    99  |  Comp005  |  2nd Floor  |
|   100  |  Comp006  |  2nd Floor  |
|   101  |  Comp007  |  2nd Floor  |
|   102  |  Comp008  |  3rd Floor  |
|   103  |  Comp009  |  3rd Floor  |
|   104  |  Comp010  |  3rd Floor  |
|--------|-----------|-------------|

第一个表COMPUSE在其中有几千条记录,因为它用于计算实验室的使用情况统计数据。我需要创建每个级别可用的计算机数量的输出。我不知道如何在不中断查询的情况下将COMPUTERS表中的位置连接到COMPUSE表中的compname。最初,我运行以下查询来确定可用的计算机总数,但我确实需要能够按建筑物的面积进行分解。

SELECT
    (SELECT COUNT(compname) 
        FROM compusage.computers) - 
    (SELECT COUNT(compname) 
        FROM compusage.compuse 
        WHERE logofftime IS NULL)

任何人都可以帮我构建一个查询,输出建筑物每层的可用计算机数量吗?此示例中的预期结果为:

Level 1:  1 computer (of 4) available
Level 2:  3 computers (of 3) available
Level 3:  2 computers (of 3) available

谢谢, 约旦

更新:这与我正在尝试做的非常类似,但我也无法弄清楚如何调整这些查询:PHP::Group and subtract two tables

更新2:这就是我现在想要适应的内容,但是我不太了解子查询以使其工作:

select (totalcomps.total - inuse.inusecomps) as available, totalcomps.total 
from (SELECT count(compname) as total, location 
         FROM compuse.computers
         GROUP BY location) as totalcomps 
inner join (SELECT count(compname) as inusecomps 
             FROM computers.compuse
             WHERE logofftime is null
             GROUP BY location) as inuse 
on computers.compname = compuse.compname

更新3:我已将示例数据更新为更多具有更多记录的真实示例。

3 个答案:

答案 0 :(得分:2)

你试过这个吗?

SELECT LOCATION, COUNT(1) as numberOfComps 
FROM COMPUTERS c
   LEFT JOIN COMPUSE cu ON c.COMPNAME = cu.Computer 
WHERE logofftime IS NULL 
GROUP BY LOCATION

答案 1 :(得分:1)

我通过基于两个单独的MySQL查询的一些PHP计算完成了这项任务。这是有效的,但我更喜欢构建一个执行相同操作的SQL查询。这是PHP:

    <?php
    $username = "user"; $password = "passwd"; $database = "compusage";

    mysql_connect(localhost,$username,$password);
    @mysql_select_db($database) or die( "Unable to select database");
    $inUseQuery = "SELECT location, COUNT(1) as inUseComps 
    FROM compusage.computers
       INNER JOIN compusage.compuse ON computers.compname = compuse.compname
    WHERE logofftime IS NULL
    GROUP BY LOCATION";

    $totCompsQuery="SELECT location, COUNT(compname) as totComps 
    FROM compusage.computers
       GROUP BY LOCATION";

    $result = mysql_query($inUseQuery);
    $inUseNum = mysql_numrows($result);
    $totCompsResult = mysql_query($totCompsQuery);
    $totCompsNum = mysql_numrows($totCompsResult);
    mysql_close();

    $i=0;
    while ($i < $inUseNum) {

    $numCompsInUse=mysql_result($result,$i,"inUseComps");
    $inUseLocation=mysql_result($result,$i,"location");
    $inUseArray[$inUseLocation] = $numCompsInUse;

    $i++;
    }

    $i=0;
    while ($i < $totCompsNum) {

    $totComps=mysql_result($totCompsResult,$i,"totComps");
    $totCompsLocation=mysql_result($totCompsResult,$i,"location");
    $totCompsArray[$totCompsLocation] = $totComps;

    $i++;
    }

    while($totCompsKey = key($totCompsArray)) {
            if (array_key_exists($totCompsKey, $inUseArray)) {
                $availFloor = $totCompsArray[$totCompsKey] - $inUseArray[$totCompsKey];
                if ($availFloor == "1") {
                    printf("<li>%s: %s computer available.</span></li>", $totCompsKey, $availFloor);
                    }
                else {
                    printf("<li>%s: %s computers available.</span></li>", $totCompsKey, $availFloor);
                    }
                }
            else {
                printf("<li>%s: all computers in use.</span></li>", $totCompsKey);
                }
        next($totCompsArray);
    }

    ?>

答案 2 :(得分:0)

SELECT LOCATION, COUNT(compID) as Available 
FROM COMPUTERS C1
INNER JOIN COMPUSE C2 ON C1.COMPNAME = C2.COMPNAME WHERE LOGOFF TIME IS NOT NULL
GROUP BY LOCATION