简体   繁体   中英

When grouping on a column (or set of columns) A, how to get the most common value of a column (or set of columns) B in each group of A?

I am trying to find out how many users were in a building at any given time. For this I have two tables,

Table a

Name    ENTER                  EXIT                       COMPANY    Employee
Jack    2013-01-01 01:00:00    2013-01-01 02:00:00        trilogy    Security Guard
Jane    2013-01-01 02:00:00    2013-01-01 03:00:00        trilogy    Security Guard
Judy    2013-01-03 01:00:00    2013-01-04 02:00:00        sindicate  Cleaner
Sam     2013-01-02 05:00:00    2013-01-02 08:00:00        lyop       Engineer

To find out how many people are at in the premises I created another table,

Table n

a   b
1   2013-01-01 01:00:00
2   2013-01-01 02:00:00
3   2013-01-01 03:00:00
-
-
x   2013-01-05 23:00:00

Then I joined them both together to find the total users at any given time using

  SELECT DATE(n.b), HOUR(n.b), COUNT(*)
  FROM
  a INNER JOIN n ON n.b BETWEEN a.ENTER
  AND a.EXIT 
  GROUP BY 1, 2

Result =

Date(n.b)    Hour(n.b)    Count(*)
2013-01-01   1            1
2013-01-01   2            2
2013-01-01   3            1
---
---
2013-01-02   5            1
so on....

This works for what I wanted. However now I want to be able to tell the top company(Regardless of Employee type) and top employee (Regardless of company) type occupation of the building per hour too IN ADDTIONAL TO THE UPPER RESULT.

eg for

 Date         Hour  Count(*)     Top-Company  Comp-Count   Top-Employe      Emp-Count 
 2013-01-01   01    1              Trilogy      1          Security Guard    1
 2013-01-01   02    2              Trilogy      2          Security Guard    2

I would like to incorporate this into my existing query, if possible. I have very little knowledge of MySQL.

A general way to do this kind of thing is to build up the complex relations you need from simpler relations. You can treat a query like a table and group it again or join it to a table or another query. Let's do the company first.

This gets you the count of employees in each company in each date+time:

select date(n.b) end_date, hour(n.b) end_hour, a.company, count(*) employees_present
from n, a
where n.b between a.enter and a.exit
group by 1, 2, 3;

This gets you the largest number of employees that any one company has in each date+time (but loses the company name in the group by):

select end_date, end_hour, max(employees_present) max_employees_present
from (
  select date(n.b) end_date, hour(n.b) end_hour, a.company, count(*) employees_present
  from n, a
  where n.b between a.enter and a.exit
  group by 1, 2, 3
) company_counts
group by 1, 2;

Join them to get the company name back:

select company_counts.end_date, company_counts.end_hour, company_counts.company
from
(
  select date(n.b) end_date, hour(n.b) end_hour, a.company, count(*) employees_present
  from n, a
  where n.b between a.enter and a.exit
  group by 1, 2, 3
) company_counts,
(
  select end_date, end_hour, max(employees_present) max_employees_present
  from (
    select date(n.b) end_date, hour(n.b) end_hour, a.company, count(*) employees_present
    from n, a
    where n.b between a.enter and a.exit
    group by 1, 2, 3
  ) company_counts_2
  group by 1, 2
) max_company_counts
where company_counts.end_date = max_company_counts.end_date and
  company_counts.end_hour = max_company_counts.end_hour and
  company_counts.employees_present = max_company_counts.max_employees_present;

After you get through the foregoing you should be able to

  • join the entire thing to your original query (which has the total count in each date+time), and
  • do it again for employee type.

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