MySQL join tables for counts with multiple conditions - mysql

Trying to create a report across 3 tables - company, account, user. For each company, there's an ID in account. Each user has an account. I can get totals easily enough, but I need to add count of how many users out of the total are registered (username is not null).
SELECT c.c_name, c.c_groupnumber, count(a.a_userid) AS TotalCount
FROM company c
LEFT JOIN account a ON c.c_groupnumber = a.a_groupnumber
WHERE a.a_deleted IS NULL
GROUP BY c.c_groupnumber
HAVING TotalCount > 0;
How can I add in a condition that gives me a count of user.u_username not null while maintaining my TotalCount? The link between account and user is
a.a_userid = user.u_userid
tbl.company
c_id, c_groupnumber, c_name
1 1234 widgets, inc.
2 5678 joe's garage
tbl.user
u_userid, u_username, u_name
1 bill Bill Smith
2 frank Frank Johnson
3 NULL Jane Doe
4 mary Mary Stack
5 NULL Steve Spot
tbl.account
a_id, a_userid, a_groupnumber
100 1 1234
101 2 5678
102 3 5678
103 4 1234
104 5 1234
So using the above very simplified table example, company "Widget's Inc." has 3 employees (bill smith, mary stack and steve spot), and of those 3 2 have registered (bill and mary), while steve has not (username is null).
Joe's Garage has 2 employees - Frank and Jane, and Frank has registered, while Jane has not.
I'd love to generate a report something like this:
Group Company Total Emp Reg Emp
1234 Widgets Inc 3 2
5678 Joe's Garag 2 1
Hopefully that makes the question clearer?

What if you get the count of username and then perform a JOIN with that like
SELECT c.c_name, c.c_groupnumber, count(a.a_userid) AS TotalCount,
xxx.username_count
FROM company c
LEFT JOIN account a ON c.c_groupnumber = a.a_groupnumber
LEFT JOIN ( select u_userid, count(u_username) username_count
from `user`
group by u_userid ) xxx ON a.a_userid = xxx.u_userid
WHERE a.a_deleted IS NULL
GROUP BY c.c_groupnumber
HAVING TotalCount > 0;

Related

Query that provides the names of the recruiters that hire more than 3 employees, and the number of employees that were not hired by a recruiter

I'm a bit stuck on this question and was hoping for some help. Here's where I'm at currently.
I have this TEST table of Names. Each Person can either be a recruiter or an employee. The number in Recruited_by is associated with the person_id.
Person_id Name Recruited_by
1 Jean Grayson 1
2 Paul Smith 7
3 John Do Null
4 Alex Lee 7
5 Lisa Kim 7
6 Bob Thompson 3
7 Mike Keen Null
8 Raymond Red 3
9 Alisson Jones 1
10 Kate James 3
Here is the query I have so far which I'm trying to the names of the recruiters that hire more than 3 employees (which will return nothing in this case) and the number of employees that were NOT recruited by anyone (which would be the NULL names).
SELECT T.Name as Employees, COUNT(T1.Name) as Not_hired
FROM Test AS T
WHERE COUNT(T1.Name) IS NULL
LEFT OUTER JOIN Test AS T1
ON T.Recruited_by = T1.Person_id
GROUP BY T.Name
HAVING COUNT(T1.Name) > 3
However this query is returning nothing when I should expect it to return the number of employees who were not hired by a recruiter!
If you want in the results only 1 row with 2 columns then you can do a LEFT join of the table to a query that aggregates to get the ids of the persons that hired more than 3 persons and aggregate again to get the number of persons that were not recruited by anyone:
SELECT GROUP_CONCAT(CASE WHEN t2.Recruited_by IS NOT NULL THEN t1.Name END ORDER BY t1.Name) names,
SUM(t1.Recruited_by IS NULL) total_not_recruited
FROM Test t1
LEFT JOIN (
SELECT Recruited_by
FROM Test
GROUP BY Recruited_by
HAVING COUNT(*) > 3
) t2 ON t2.Recruited_by = t1.Person_id;
You will get the names of the persons that hired more than 3 persons (if they exist) as a comma separated list.
See the demo.

SQL identify the first name and last name, that is assigned to tasks to what company

I have 3 Tables, new to SQL, I'm Trying to Combine 2 tables (Users and Tasks) into Companies or into a new table. What I need is to probably replace under Companies Table: TaskID and UserID with TaskID and UserID in both Users Tasks and table, but I get an error
SELECT COMPANY.UserID, COMPANY.TaskID, (FirstName+' '+LastName) AS FullName, TASKS.TaskSubject, USERS.UserID
FROM USERS, TASKS, COMPANY
INNER JOIN COMPANY.UserID = USERS.UserID
INNER JOIN COMPANY.TaskID = TASKS.TaskSubject
USERS:
UserID FirstName LastName
1 John Green
2 Graham Dale-Jones
3 Francois Peters
4 Danika Snow
5 Jennifer Booth
6 Erin Harvey
7 Caleb Jackson
TASKS:
TaskID TaskSubject TaskManager
101 Install
102 Upgrade
103 Troubleshoot
104 Assign
COMPANY:
CompanyID TasksID UserID
1 101 1
1 101 2
2 102 2
3 103 3
4 103 4
5 104 7
Thank you for the help
Try the following, you first need to learn how to join. What you are using is implicit join (on where) which is not best practice, instead you should always use explicit join.
SELECT
c.UserID,
c.TaskID,
concat(FirstName, ' ' ,LastName) AS FullName,
t.TaskSubject,
u.UserID
FROM users u
INNER JOIN company c
on c.UserID = u.UserID
INNER JOIN tasks t
on c.TaskID = t.TaskId
Here is the demo.

UNION ALL not working with different columns

Left join rows and right table rows in same column
I have two tables (Manager and Worker). The name of workers under a manager should come below manager name. The expected output is presented below:-
Manager Table:
ManagerCode Name Age Location
1 Chris 52 A
2 Rick 55 B
3 David 50 C
Worker Table
ManagerCode WName Age
1 Harry 33
1 Phil 40
2 Johnny 28
2 Jeff 47
Expected table:
ManagerCode Name Location
1 Chris A
1 Harry A
1 Phil A
2 Rick B
2 Johnny B
2 Jeff B
3 David C
Union All is creating problem for Location column as number of columns become different. I could use null as Location for worker table. But there are several columns like location in Manager. Is union correct option ?
You need to join the Worker and Manager tables to get the location codes for the workers from their corresponding managers. Then you can union that with the manager table.
SELECT ManagerCode, Name, Location
FROM (
SELECT ManagerCode, Name, Location, 1 AS isManager
FROM Manager
UNION ALL
SELECT w.ManagerCode, w.Name, m.Locationm, 0 AS isManager
FROM Worker AS w
JOIN Manager AS m ON w.ManagerCode = m.ManagerCode
) AS x
ORDER BY ManagerCode, isManager DESC
The isManager column is used to order the workers after their managers.

how to get multiple items in one line in mysql?

I have an employees table, which has all the information about employees, including the manager_id, for example:
id name manager_id
1 Joe 5
2 Mary 5
3 Bill 5
4 Jane 6
5 Matt 6
6 Walt 7
I would like to get a list of people, and for each one all their direct reports. Is it possible to create a query to give me the following output:
Employee Direct Reports
Joe
Mary
Bill
Jane
Matt Joe, Bill, Mary
Walt Jane, Matt
This way:
SELECT s.name AS employee, group_concat( e.name )
FROM employees s
LEFT OUTER JOIN employees e ON s.id = e.manager_id
GROUP BY s.id
You have to join the table with itself. And you need to use left join, so that you get the employees who don't manage anyone.

Slightly complex MySQL query

employees
e_id first last
1 John Smith
2 Bob Smith
3 Alex Smith
4 John Doe
5 Ron Doe
clockpunch
e_id time for adjustment
1 0650 in early
3 0710 in late
4 0725 in early
1 1100 lunch ---
2 1150 in late
2 1400 lunch ---
4 1320 out ---
I need a SINGLE query that will list all employee names, along with a count of how many times that user has been early, descending order by the count of times early. How would this be done ?
select a.first,a.last,sum(case b.adjustment when 'early' then 1 else 0 end) as ct
from employees a, clockpunch b where a.e_id=b.e_id
group by a.first, a.last
This might work (untested)
select first,last,count(*) from employees e, clockpunch c
where e.e_id = c.e_id and adjustment = 'early'
group by first,last
order by count(*) desc