Error on SQL JOIN on 2 nested COUNT and GROUPBY statements - mysql

I am trying to combine 2 queries, one counting the users in each country and the other counting the users in each country using public phones and merging the columns together. However, I keep getting an error near the inner join code region. I am using HeidiSQL so that is the only error message I get. Each nested query runs perfectly on its own. Anyone knows what's wrong?
SELECT
AllUsers.country,
AllUsers.TotalUsers,
PublicUsers.PublicPhoneUsers
FROM
(SELECT
country,
count(country) As "TotalUsers"
FROM
userlist
GROUP BY
country) AS "AllUsers"
INNER JOIN
(SELECT
country,
count(country) As "PublicPhoneUsers"
FROM
userlist
WHERE
phone_public = 1
GROUP BY
country) AS "PublicUsers"
ON
AllUsers.country = PublicUsers.country;

Please remove the double quotation marks from both your column and table aliases:
SELECT AllUsers.country, AllUsers.TotalUsers, PublicUsers.PublicPhoneUsers
FROM
(
SELECT country, COUNT(country) As TotalUsers
FROM userlist
GROUP BY country
) AS AllUsers
INNER JOIN
(
SELECT country, COUNT(country) As PublicPhoneUsers
FROM userlist
WHERE phone_public = 1
GROUP BY country
) AS PublicUsers
ON AllUsers.country = PublicUsers.country

Related

SQL: Where this exists -> Compare two tables and check if they have the same number of rows

I am at the end of my SQL knowledge. I have the problem that I want to check for existence whether two tables have the same number of rows.
An example could be that I want to show all schools where the number of chairs are the the same number of students. My pseudo Code looks like this:
SELECT * FROM schools WHERE
((SELECT COUNT(*) FROM students) = (SELECT COUNT(*) FROM chairs));
or with a pseudo calculation: students - chairs = 0;
SELECT * FROM schools WHERE
((SELECT COUNT(*) FROM students) - (SELECT COUNT(*) FROM chairs) = 0);
Is such a construction with SQL possible and if so how?
Your approach seems a little unorthodox, but you can do it with correlated subqueries:
SELECT s.*
FROM schools s.
WHERE ( (SELECT COUNT(*) FROM students st WHERE st.school_id = s.school_id) =
(SELECT COUNT(*) FROM chairs c WHERE c.school_id = s.school_id)
);
I would be more inclined to do a join after aggregation:
select st.school_id
from (SELECT st.school_id, COUNT(*) as cnt
FROM students st
GROUP BY st.school_id
) st JOIN
(SELECT c.school_id, COUNT(*) as cnt
FROM chairs c
GROUP BY c.school_id
) c
ON st.school_id = c.school_id AND st.cnt = c.cnt;
The two versions are subtly different. This version will only return school ids that have at least one student (and chair).
EDIT:
I should note that if you just want to know if two tables have the same number of rows, you can return a boolean in the SELECT:
SELECT ( (SELECT COUNT(*) FROM chairs c) =
(SELECT COUNT(*) FROM students st)
) as num_rows_same_flag
Because of the presence of the schools table, though, I assume you want the schools with the same numbers of each.

Combine 2 Select queries with different conditions

i current have 2 Select queries at mySQL.
SELECT Provider Name, Country, GroupUpdateID FROM provider WHERE Country="Vietnam" AND Provider Name="Provider A"
SELECT GROUP_CONCAT(DISTINCT Country) AS result FROM provider WHERE GroupUpdateID="Group1"
How can i combine these 2 queries such that i am able to display the provider Name, Country, groupUpdateID and a new column named Result (which will contain country names which share the same GroupUpdateID)?
I am stuck because i have no idea on how to produce a single query since they both have different WHERE criteria.
Modify your second query such as to get the country list per GroupUpdateID (i.e. use GROUP BY):
SELECT
p.ProviderName,
p.Country,
p.GroupUpdateID,
c.result
FROM provider p
JOIN
(
SELECT GroupUpdateID, GROUP_CONCAT(DISTINCT Country) AS result
FROM provider
GROUP BY GroupUpdateID
) c ON c.GroupUpdateID = p.GroupUpdateID
WHERE p.Country = 'Vietnam'
AND p.ProviderName = 'Provider A';
Or use a correlated subquery in the SELECT clause:
SELECT
ProviderName,
Country,
GroupUpdateID,
(
SELECT GROUP_CONCAT(DISTINCT c.Country)
FROM provider c
WHERE c.GroupUpdateID = p.GroupUpdateID
) AS result
FROM provider p
WHERE Country = 'Vietnam'
AND ProviderName = 'Provider A';

How to merge 2 separate query and group by specific field with group_concat

I have used UNION for 2 separate Mysql query, The query is as below.
select country,u_id from
(SELECT regionShortName as country , GROUP_CONCAT( urls_regions.u_id ) AS
u_id
FROM urls_regions
where LENGTH(regionShortName )<=2
GROUP by regionShortName)
UNION
(SELECT countries.name as country,
GROUP_CONCAT( urls_regions.u_id ) AS u_id
FROM `countries` countries
inner join regions on countries.regions_id = regions.id
INNER JOIN urls_regions ON regions.region = urls_regions.regionShortName
GROUP by countries.name, country)
The above query has given me the results as below,
I am not able to achieve as below,
Now I would like know how to group by the "country" by concat(merge or join) "u_id"
Is my query implemented is right approach or is there any other approach to achieve this.
Using below query I am able to get what I am expecting,
select tb.country, GROUP_CONCAT(tb.u_id, ',') from
((SELECT regionShortName as country , GROUP_CONCAT( urls_regions.u_id ) AS
u_id
FROM urls_regions
where LENGTH(regionShortName )<=2
GROUP by regionShortName)
union
(SELECT countries.name as country,
GROUP_CONCAT(urls_regions.u_id ) AS u_id
FROM `countries` countries
inner join regions on countries.regions_id = regions.id
INNER JOIN urls_regions ON regions.region = urls_regions.regionShortName
GROUP by countries.name, country)) tb group by tb.country
I have done 2 things
In my first line of query I have added GROUP_CONCAT(tb.u_id, ',')
In the last line added group by tb.country

How to use MAX and COUNT function in MYSQL with 2 tables

I am a newbie in MYSQL and had a question regarding the use of MAX and COUNT functions together in MYSQL. I have 2 tables worker and assignment and the primary key of worker is a foreign key in assignment table.
I need to show the employees name and id and the total assignment assigned to him, and only show the person with the most assignment that is the employee with the most assignment.
my code is
SELECT worker.Wrk_ID, worker.Wrk_LastName, MAX(a.count_id)
FROM worker,
(SELECT COUNT(assignment.Wrk_ID) as count_ID
FROM worker, assignment
WHERE worker.Wrk_ID = assignment.Wrk_ID
GROUP BY worker.Wrk_ID)as a
GROUP BY worker.Wrk_ID;
The code is giving an error no. #1054.
Please can anyone help me.
Thanking you in anticipation.
Try something like this:
SELECT worker.Wrk_ID, worker.Wrk_LastName, S.Count
FROM worker
JOIN
(SELECT Wrk_ID, COUNT(*) AS Count FROM Assignments
GROUP BY Wrk_Id ORDER BY COUNT(*) DESC LIMIT 1) S
ON worker.Wrk_ID = S.Wrk_ID
If you want a list of employees sorted by their total assignments:
SELECT w.WrkID, w.Wrk_LastName, COUNT(*) AS Assignments
FROM work w left join Assignments a
ON w.WrkID=a.WrkID
GROUP BY w.WrkID
ORDER BY COUNT(*) DESC;
To allow multiple winners:
SELECT s.*, w.Wrk_Lastname FROM
(
SELECT wrk_id , COUNT(*) AS tot_assignments
FROM Assignments
GROUP BY wrk_id
HAVING COUNT(*) =
(
SELECT MAX(tot) FROM
(
SELECT COUNT(*) AS TOT FROM Assignments GROUP BY wrk_id
) counts
)
) winners
INNER JOIN worker w ON s.wrk_id = w.wrk_id;
It can be slow since it does multiple GROUP BY. Doing it in separated steps in a procedure can be better.

MySQL nested counts and returning values

I have searched high and low and can't seem to get a way to do what I want. I have a table with some customers, some products and their relationships.
I want to count the amount of returned rows from this part of the query
SELECT id
FROM customer
WHERE customer.name = 'SMITH'
OR customer.name = 'JONES'
I also want to return the ids that match SMITH and JONES (or other customer names chosen). I want to use the count of the returned rows as a variable (denoted as #var). I only want to return the products, id, and count that match my variable.
My questions are:
Is there a way that this can be done in a single SQL query?
Is there a way to return the count as well as the values?
I don't want to have to throw this into a PHP script or the like.
SELECT x.pId, p.productdesc, count(x.dId) as count
FROM
(
SELECT DISTINCT cId, pId
FROM Client
WHERE cId IN
(
SELECT id
FROM customer
WHERE customer.name = 'SMITH'
OR customer.name = 'JONES'
)
)x
JOIN Products p ON x.pId = p.id
GROUP BY x.pId
HAVING count = #var
Thanks,
M
This is sort of a 'literal' answer to what your asked, as you can use subqueries in the having clause. However, with more information (sample data and expected result) there may be a better way of doing what you want.
select x.pid, p.productdesc, count(x.pid) as count
from (select distinct cl.cid, cl.pid
from client cl
join customer cu
on cl.cid = cu.id
where cu.name in ('SMITH', 'JONES')) x
join products p
on x.pid = p.id
group by x.pid, p.productdesc
having count(x.pid) = (select count(*)
from customer
where name in ('SMITH', 'JONES'))