Why are many rows of the same name showing in MySQL php? - mysql

I tried to INNER JOIN two tables and when I use '=' it works, but when I use '!=' it doesn't work anymore. The result is a lot of rows with the same value.
For example
name:
john
john
john
john
john
mary
mary
mary
mary
lisa
lisa
lisa
lisa
lisa etc... (many other names)
this is my code.
SELECT part_names FROM participants INNER JOIN reservations ON participants.part_id != reservations.part_id
the crazy thing is e.g. that I get 5 John's, 5 Lisa's and only 4 Mary's (mary should not be showing as her participants id does match the one in reservations. How do I solve this that I only get to see the participants whose part_id in table participants doesn't match in the reservations table? and only 1, so not Lisa Lisa Lisa Lisa Lisa but just Lisa.
thanks!

I'm pretty sure you want a left join and comparison to NULL:
SELECT p.part_names
FROM participants p LEFT JOIN
reservations r
ON p.part_id = r.part_id
WHERE r.part_id IS NULL;
That is, look for matches and then return the rows with no match.

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.

I want to join two tables, removing duplicate values

I have to say I'm an amateur on MySQL, plus english is not my mother's language.
Here is my first table "Teacher":
ID Name Procedence
1 John Italy
2 Mike Russia
3 Lauren Spain
4 Arnold Spain
And here my second table "Course":
ID1 CourseName
1 Sailing
1 Football
2 Basketball
2 Hockey
I would like to know which country has more teachers giving courses, but I don't want that it count the same teacher twice. So far I made this:
SELECT Procedence, Count(Procedence) as Procedence_Count
from Teacher INNER JOIN Course
ON Course.ID1 = Teacher.ID
GROUP by Procedence
having Procedence_Count > 1;
When I run this, I obtain:
Procedence Procedence_Count
Italy 2
Russia 2
But the code counts John and Mike as two persons, I would like to remove that duplicity, so I would like to obtain:
Procedence Procedence_Count
Italy 1
Russia 1
Thanks a lot.
Use count(distinct):
select Procedence, Count(distinct t.id) as teacher_count
from Teacher t join
Course c
on c.ID1 = t.ID
group by Procedence
having teacher_count > 1;
One additional note: "procedence" is not at all a common English word. One word is "provenance". I think more commonly "origin" or just "country" would be used.

MySQL join tables for counts with multiple conditions

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;

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.

How to get hierarchy of employees for a manager in mysql?

I have an employee table, with the following data.
For a particular manager, i want to get the list of all employees, following the hierarchy of the manager.
id name manager
1 John 6
2 Gill 7
3 Ben 2
4 Roy 8
5 Lenin 6
6 Nancy 7
7 Sam 0
8 Dolly 3
For example, i have to get the employees under manager Sam(7). As you can see, Sam does not have any manager, but he is the manager for employees Gill and Nancy, who are the managers for employees Ben and John, Lenin respectively.
So i ran a query like this:
select * from employee where manager=7;
I get the result as 2 rows, Gill and Nancy.
But now, i also want to show the employees Ben and John, Lenin in the output, as they both are under the managers Gill and Nancy, who are under Sam.
How can i structure the query to show the employees hierarchically for a manager? In other words, how can i show all Gill, Nancy, Ben, John and Lenin under the manager Sam ?
Adding a IN subquery to your WHERE clause will handle that. For example:
SELECT * FROM employee WHERE manager = 7 OR manager IN (SELECT id FROM employee WHERE manager = 7)
For a better visuality you can also use this query:
select e1.name, e2.name, e3.name
from employee e1
left join employee e2 on e1.id = e2.manager
left join employee e3 on e2.id = e3.manager
where e2.manager = 7
whereas you have to add another left join for each hierarchy. That is a downside on the one hand, on the other hand it's easier to handle than in Sean's answer.
On the pro side you get an output like this:
name name1 name2
---------------------------------
Sam Gill Ben
Sam Nancy John
Sam Nancy Lenin
which is much more eye friendly and you can easily put it in an even more eye friendly form via PHP or something.