如何计算涉及多个表的多个列的平均值和计数?

时间:2012-04-29 15:15:18

标签: php mysql sql

以下是我的不同表格:

computers (id,name)
monitors (id,name)
computer_monitor (id, computer_id,monitor_id)
useractivity (id,userid,timestamp,computer_monitor_id,ip)
useropinion (id,userid,computer_monitor_id,timestamp,rating)
user (id,name,email)

我想搜索计算机或监视器的名称,并获得这样的行作为回报:

computer name and/or monitor name
computer_monitor_id
avg(rate)
count(useractivity)

avg(rate)位于与该名称匹配的特定computer_monitor_id上,计数也是如此。

与monitor无连接的计算机在computer_monitor表的monitor字段中的值为0,反之亦然monitor->computer

useractivity和useropinion仅包含computer_monitor表中的ID

3 个答案:

答案 0 :(得分:1)

据我了解,查询应围绕computer_monitor表构建。所有其他表都连接到它,包括那些您想从中获取统计数据的表。

SELECT
  c.name AS ComputerName,
  m.name AS MonitorName,
  uo.AverageRating,
  ua.ActivityCount
FROM computer_monitor cm
  LEFT JOIN computer c ON c.id = cm.computer
  LEFT JOIN monitor  m ON m.id = cm.monitor

  INNER JOIN (
    SELECT computer_monitor_id, AVG(rating) AS AverageRating
    FROM useropinion
    GROUP BY computer_monitor_id
  ) uo ON cm.id = uo.computer_monitor_id

  INNER JOIN (
    SELECT computer_monitor_id, COUNT(*) AS ActivityCount
    FROM useractivity
    GROUP BY computer_monitor_id
  ) ua ON cm.id = ua.computer_monitor_id

实际上,正如您所看到的,useropinionuseractivity首先汇总,然后加入。这是为了避免computer_monitor.iduseropinionuseractivity中匹配多行时Cartesian product效果。

答案 1 :(得分:0)

<?php
$res_comp = mysql_query("select * from computers where name = '$name'");
$res_monitor = mysql_query("select * from monitor where name = '$name'");
if(mysql_num_rows($res_comp) > 0)
{
$row_comp = mysql_fetch_array($res_comp);
$comp_id = $row_comp['id'];
$res_result = mysql_query("select computers.name, computer_monitor.id, count(computer_monitor_id) from computers, computer_monitor, useractivity where computers.id = '$comp_id' AND computer_monitor_id = '$comp_id' AND useractivity.computer_monitor_id = '$comp_id'");

}
// repeat the same for monitor also. then use mysql_fetch_array to show your data.
?>
希望这会有所帮助。

答案 2 :(得分:0)

这个可能可以做到这一点......(一个带有计算机/监视器关系的表,另一个带有外部参照表的表扔给我,并根据您的数据检查连接类型)

SELECT computers.name AS ComputerName
    , monitors.name AS MonitorName
    , AVG(useropinion.rating) AS AvgRating
    , COUNT(useractivity.id) AS ActivityCount
FROM computers
INNER JOIN computer_monitor ON (computers.id = computer_monitor.computer_id)
INNER JOIN useractivity ON (computers.id = useractivity.computer_id)
INNER JOIN monitors ON (computer_monitor.monitor_id = monitors.id)
INNER JOIN useropinion ON (computer_monitor.id = useropinion.computer_monitor_id) AND (monitors.id = useractivity.monitor_id)
INNER JOIN USER ON (useropinion.user_id = user.id) AND (useractivity.user_id = user.id)