access sql inner join and count in 2 tables - sql

I have a question about sql queries in access (i just started like 3 days ago)
so there are 2 tables: employes and departments, what i want is to create a query which will show the name and id of each employe and how many departments he manages.
Employee( ID, NAME, social_security_of_employe)
Department(department_id, social_security_of_employee)
(social security is my primary key)
my try was:
SELECT E.ID, E.NAME, COUNT(D.SOCIAL_SECURITY) AS NUMBER_OF_DEPARTMENTS
FROM EMPLOYEE E
INNER JOIN DEPARTMENT D
WHERE D.SOCIAL_SECURITY=E.SOCIAL_SECURITY
GROUP BY SOCIAL_SECURITY
thanks in advance

The correct syntax for MS Access is:
SELECT E.ID, E.NAME, COUNT(D.SOCIAL_SECURITY) AS NUMBER_OF_DEPARTMENTS
FROM EMPLOYEE as E INNER JOIN
DEPARTMENT as D
ON D.SOCIAL_SECURITY = E.SOCIAL_SECURITY
GROUP BY E.ID, E.NAME;
Changes:
MS Access requires as for table aliases.
The WHERE clause should be an ON clause.
The columns in the GROUP BY need to match the unaggregated columns in the SELECT.

You need to group by all non-aggregated columns listed in the select list, i.e.:
SELECT E.ID, E.NAME, COUNT(D.SOCIAL_SECURITY) AS NUMBER_OF_DEPARTMENTS
FROM EMPLOYEE E
INNER JOIN DEPARTMENT D
ON D.SOCIAL_SECURITY=E.SOCIAL_SECURITY
GROUP BY E.ID, E.NAME;
and not on SOCIAL_SECURITY (you are using the COUNT aggregate on it)
Because E.ID and E.NAME are directly correlated, there will only be a single level of grouping.

Related

SQL Joins and Corelated subqueries with column data

I am facing an issue in terms of understanding the joins. Lets say for an example we have two tables employee and sales and now I have a query where we have sales of an employee using the id of the employee
select e.employeename
,s.city
,SUM(s.sales)
from employee e
left join (select sales,eid from sales) s on s.eid = e.id
group by 1,2
I'd like to understand why s.city wasn't showing up? and also would like to understand what is this concept called? Is it co related sub queries on Joins? Please help me down over here.
select
e.employeename
,s.city
,SUM(s.sales)
from employee e
left join (select sales,eid,city from sales) s on s.eid = e.id
group by 1,2
in the left join above you have to add city as well. The query Imagine select sales,eid,city from sales is a table itself and then from this table you are selecting city (your second column s.city) this will run error as your table doesn't have a city column yet.
It is much easier to use CTE (common table expressions than CTE's) You can also do the above question as
select
e.employeename
,s.city
,SUM(s.sales)
from employee e
left join sales as s
on e.id = s.id
group by 1,2
here I have added e.id = s.id instead of s.id = e.id it is better to reference the key of the main table first.
you could use CTE (although used when you have to do a lot of referencing but you can see how it works):
With staging as (
select
e.employeename
,s.city
,s.sales
from employee e
left join sales as s
on e.id = s.id
),
sales_stats as (
select
staging.employeename,
staging.city,
sum(staging.sales)
from staging
group by 1,2
#here you will select from staging again consider staging as a separate table so you will have to have all the columns in the staging that you want to use further. Also you will have to reference columns using staging.x
)
select * from sales_stats
-- here you could have combined the steps but I wanted to show you how cte works, Hope this works for you

How to use count and order by with inner join in mysql?

employee table
department table
How to display department name and number of employees working for that department.
My SQL code:
SELECT department.dname , employee.count(*)
FROM employee
INNER JOIN department
ON dno=dnumber
ORDER BY department.dname;
The correct syntax is:
select d.dname, count(*)
from employee e inner join
department d
on d.dno = e.dnumber
group by d.dname
order by d.dname;
Notes:
You are describing an aggregation query with one row per department. That suggests GROUP BY.
Table aliases make the query easier to write and to read.
Qualify all column names. I have to guess what table dno comes from. There should be no reason to guess.

Joining two tables with specific columns

I am new to SQL, I know this is really basic but I really do not know how to do it!
I am joining two tables, each tables lets say has 5 columns, joining them will give me 10 columns in total which I really do not want. What I want is to select specific columns from both of the tables so that they only show after the join. (I want to reduce my joining result to specific columns only)
SELECT * FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
The syntax above will give me all columns which I don't want. I just want EmpName, Address from the tblEmployees table and Name, Address, project from the tbSupervisor table
I know this step:
SELECT EmpName, Address FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
but I am not sure about the supervisor table.
I am using SQL Server.
This is what you need:
Select e.EmpName, e.Address, s.Name, S.Address, s.Project
From tbEmployees e
JOIN tbSupervisor s on e.id = SupervisorID
You can read about this on W3Schools for more info.
You can get columns from specific tables, either by their full name or using an alias:
SELECT E.EmpName, E.Address, S.Name, S.Address, S.Project
FROM tbEmployees E
INNER JOIN tbSupervisor S ON E.ID = S.SupervisorID
You can use the table name as part of the column specification:
SELECT tbEmployees.EmpName, tbEmployeesAddress, tbSupervisor.Name,
tbSupervisor.Address, tbSupervisor.project
FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
SELECT employees.EmpName, employees.Address AS employeer address,
supervisor.Name, supervisor.Address AS supervisor address,supervisor.project
FROM tbEmployees
AS employees
JOIN tbSupervisor
AS supervisor
ON
employees.ID = supervisor.SupervisorID
You need to learn about aliases. They will make your queries more maintainable. Also, you should always use aliases when referencing columns, so your query is clear about what it is doing:
SELECT e.EmpName, e.Address, s.name, s.address as SupervisorAddress
FROM tbEmployees e JOIN
tbSupervisor s
ON e.ID = s.SupervisorID;
Note that I also renamed the second address so its name is unique.
Specify the table name and field name in your selection
SELECT tbEmployees.EmpName,
tbEmployees.Address,
tbSupervisor.[column name]
FROM tbEmployees
JOIN tbSupervisor ON tbEmployees.ID = tbSupervisor.SupervisorID
SELECT product_report.*,
product.pgroup
FROM `product_report`
INNER JOIN product
ON product_report.product_id = product.id
WHERE product.pgroup = '5'
ORDER BY product.id DESC

Right Outer join issue

I've two tables that I want to join and filter data from. I used a stored procedure to do that. My intention is to bring every item from the second table (i.e Department) even if they don't have a matching record in the first table (i.e. Employee) and finally display the count. Here is the segment of the code I used:
select d.deptName,
case when COUNT(*) is null then '0' else count(*) end AS total
from Employee e
right outer join Department d on e.deptID=d.deptID
WHERE e.Year=#year
and e.Month=#month
group by d.deptName
order by d.deptName
But, it's not displaying what i wanted and failed to figure out the real problem.
When you apply the filter condition through where clause after join, it filters out all the records which doesn't satisfy the filter criteria. Try moving your filter criteria in join condition itself as below:
select d.deptName,
case when COUNT(*) is null then '0' else count(*) end AS total
from Employee e
right outer join Department d
on (e.Year=#year
and e.Month=#month
and e.deptID=d.deptID)
group by d.deptName
order by d.deptName
I think you need to change the code like this
SELECT d.deptName, COUNT(e.deptID) AS total
FROM Employee e
RIGHT OUTER JOIN Department d
ON (e.Year= #year
AND e.Month= #month
AND e.deptID=d.deptID)
GROUP BY d.deptName
ORDER BY d.deptName
See the SQL Fiddle for the query : http://sqlfiddle.com/#!3/b1105/17

How do I join 3 tables using mysql

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.