I have this task:
Count the number of employees for every country. Show only those countries, when works more than 20 employees
employee_id is dedicated for Employees table
country belongs to different table - Countries table and we need country_name from this table
I have no idea how to solve this task. Below what I was able to create. I think we should use Inner Join.
SELECT a.employee_id
, b.country_name
, COUNT(a.employee_id) AS count
FROM employees a
INNER JOIN countries b ON a.employee_id = b.country_name
GROUP BY b.country_name
WHERE employee_id >20;
I think I need help from the beginning.
Thanks
Your join doesn't seem correct but as I don't know the table structure, I can't say what the right column is (I'm going to assume that it should be country_name. Even so, try this:
SELECT b.country_name
, COUNT(a.employee_id) AS count
FROM employees a
INNER JOIN countries b ON a.country_name = b.country_name
GROUP BY b.country_name
HAVING COUNT(employee_id) >20;
When grouping you need to use the HAVING statement to filter.
Related
I want to write a SQL query for the problem as defined below, I am not sure about the answer, can anyone help me? Is the answer correct, or if not, how can I improve it?
I have used aggregation function, how can I improve it, to write an sql without aggregation function?
Let us consider the following relational schema about physicians and departments:
PHYSICIAN (PhysicianId, Name, Surname, Specialization, Gender, BirthDate, Department);
Let every physician be univocally identified by a code and characterized by a name, a surname, a specialization (we assume to record exactly one specialization for each physician), a gender, a birth date, and the relative department (each physician is assigned to one and only one department).
DEPARTMENT (Name, Building, Floor, Chief)
Let every department be univocally identified by a name and characterized by its location (building and floor) and a chief.
Let us assume that a physician can be the chief of at most one department (the department he/she belongs to). We do not exclude the possibility for two distinct departments to be located at the same floor of the same building.
I want to formulate an SQL query to compute the following data (exploiting aggregate functions only if they are strictly necessary):
the departments which have no male physicians and with at least two physicians whose home city is Venice.
My answer is as below:
select d.name
from department d
where d.name in (select p.department from physician p where p.gender =! 'Male')
and d.name in (select p.department from physician p
where HomeCity = 'Venice'
group by p.PhysicianId
having count > 2)
Or:
select d.*
from department d
inner join physician p on d.name=p.department and
p.gender=!"Male"
left join physician o where d.name=o.department and o.birthdate='venice'
groupby birthdate
having sum(o. physicianID) >2
Assuming that both the conditions should apply at the same time, I'd say your answer is correct. I would modify it just a bit:
select d.name
from department d
where not exists (select 1 from physician p where p.gender = 'Male' and p.Department = d.name)
and d.name in (select p.department from physician p
where HomeCity = 'Venice'
group by p.department, p.HomeCity
having count >= 2)
If you go with the inner join solution, you will have to apply a distinct to your select, which will make your query slower.
The not exists clause I propose, will create an execution plan, similar to inner join. That is you will not need to compare each name with all the names of the departments without Male employees.
You can't avoid the aggregate function if you want to count something. There is a workaround with Over in TSQL but I would not recommend it.
Despite conditions are different the main idea is the same as in improving the written sql query.
You need to use the same approach but substitute your own join and where conditions.
Update
Here is a version for your case:
select distinct d.*
from departments d
left join physicians m on d.name = m.department and m.gender = 'Male'
inner join physicians v1 on d.name = v1.department and v1.homecity = 'Venice'
inner join physicians v2 on d.name = v2.department and v2.homecity = 'Venice' and v2.id <> v1.id
where m.id is null
I need to know how many employees does each company have for each country they are present in? I have to join two tables (companies and cities) and sum number of employees for each country.
SELECT *, SUM(EMPLOYEES)
FROM COMPANIES WHERE
JOIN CITIES
ON COMPANIES.CITYNAME = CITIES.CITYNAME
doesn´t work...
Tables to join and sum employees for each country
A couple of tips,
Try to alias your joins so your not typing the full table names in your join statements
Add a group by on every field your not aggregating on for your sum to work
SELECT CI.COUNTRYNAME,CO.CITYNAME,CO.COMPANYNAME,CI.POPULATION,CI.COUNTRYNAME,
SUM(EMPLOYEES) AS TOTAL_EMPLOYEES
FROM COMPANIES AS CO
JOIN CITIES AS CI
ON CO.CITYNAME = CI.CITYNAME
GROUP BY CI.COUNTRYNAME,CO.COMPANYNAME,CO.CITYNAME,CI.POPULATION
https://rextester.com/DLZNT87647
I want to know which customer from which country did the most orders. So I have a sales_table with the customer_ids. But the country_id is in the customer_table. So I need somehow to count the customers based on the country count... But I have no idea how to do it. I
I know how to count the customers.
select count(cust_id)
from sh_sales
and how to count the countries
select count(country_id)
from sh_customers
but i want to count the country based on the customer_id which is most often used in the sh_sales table
so it should somehow be
select count(country_id)
from sh_customers
where sh_sales.customer ????
I really need some help here :)
This will count the records in the sh_sales table and group out by each country_id from the customers table
SELECT country_id, count(s.cust_ID)
FROM sh_customers c
INNER JOIN sh_sales s ON c.cust_id = s.cust_id
GROUP BY country_id
If, for some reason, you could have a customer record, but no sales then you can use LEFT OUTER JOIN to return a NULL for countries without any sales
I have a table for absentees, and that table am storing the studentids of those who have been absent.
From this table I had to find total presentees and total absentees, for this I just joined the Sections table which contains the maximum capacity of particular Section.
For this my query was
select COUNT(Attendance.studentid) as Absentees
,Sections.Max-count(studentid) as Presentees
from Attendance
inner join Students
on students.StudentId=Attendance.StudentId
inner join Sections
on Sections.CourseId=students.CourseId
group by Sections.Max
Its working fine, the same way how can I find the gender wise presentees/absentees......gender column is in Students table, can anyone give me some idea, thanks in advance
Just add the gender column to your select ... columns and the group by, you'll end up with one row for each gender:
select COUNT(Attendance.studentid) as Absentees,
Sections.Max-count(studentid) as Presentees,
Students.Gender as Gender
from Attendance
inner join Students
on Students.StudentId=Attendance.StudentId
inner join Sections
on Sections.CourseId=Students.CourseId
group by Sections.Max, Students.Gender
I have the following tables:
TABLE: companies c
FIELDS: id, name, description
TABLE: departments d
FIELDS: id, name, description
TABLE employees e
FIELDS: id, company_id, department_id, name
I'm trying to get a list of all employees for company 1 and also get the department name (d.name) into the results of the row.
Here's my original query:
SELECT e.*, c.name as company
FROM employees e, companies c
WHERE e.company_id=c.id AND e.company_id=1;
What should I add to this query to get the department name (d.name) to appear in each row of the query? Also... e.department_id may be equal to 0 in some cases since there are no departments for a specific company.
Thanks for the help everyone!
SELECT e.id, e.name, e.department_id, c.name, d.name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
LEFT JOIN companies AS c ON e.company_id = c.id
WHERE e.company_id = 1;
Generally you can mix-match joins in any order, as long as any columns/tables you require in a join have already been joined previously. In this case, you're slurping up data from two separate tables that are related via the employees data, and neither of them are co-dependent, so you can order the two LEFT JOIN lines in any order.
As well, with a LEFT join, you get all rows from the table on the "left" side of the join (in this case, the employees table) and matching rows (if any) from the right table (companies/departments). If there's no matching rows in either companies or departments, then any columns coming from those tables will be NULL in the result set.