简体   繁体   中英

How do I calculate avg and count on multiple columns involving many tables?

Here are my different tables:

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)

I want to search after the name of computer or monitor and get a row like this in return:

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

avg(rate) is on that specific computer_monitor_id that matches the name, the same goes for count.

A computer with no connection to monitor has a value of 0 on monitor field in computer_monitor table and vice versa for monitor->computer .

useractivity and useropinion only contains the ID from computer_monitor table

As I understand, the query should be built around the computer_monitor table. All other tables connect to it, including those from which you want to obtain the stats.

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

Actually, as you can see, useropinion and useractivity are aggregated first, then joined. This is to avoid the Cartesian product effect when a computer_monitor.id matches more than one row both in useropinion and in useractivity .

<?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.
?>

hopefully this will help.

This might do the trick...(one table with the computer/monitor relation ship, the other with a xref table threw me, and check the join types depending on your data)

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM