I have three tables area,vehicle and employee.
ward_no is the foreign key for vehicle and employee.
I want to select the number of vehicles and number of employees and display them along with other details of area.
The query i used is:
select a.* ,count(v.vid) as vehicles,count(e.eid) as employees from area a,vehicle v,employee e where v.ward_no=a.ward_no and e.ward_no=a.ward_no group by a.name;
But the output is not what I want. I get the same values in both the columns where the count is use instead of displaying the total number of vehicles/employees in that particular area.
I'm new to MySQl
The default behavior of count is to count the non-null values.
In your case, this counts repetitions of the value.
Try adding DISTINCT inside the count:
select a.* ,count(DISTINCT v.vid) as vehicles,count(DISTINCT e.eid) as employees
from area a,vehicle v,employee e
where v.ward_no=a.ward_no and e.ward_no=a.ward_no group by a.name;
Also, it's better to use explicit JOIN rather than implicit, like this:
select a.* ,count(DISTINCT v.vid) as vehicles,count(DISTINCT e.eid) as employees
from area a JOIN vehicle v ON v.ward_no=a.ward_no
JOIN employee e ON e.ward_no=a.ward_no
group by a.name;
There may be a chance that you are getting same vehicle and employee multiple times due to the joins, Use DISTINCT in COUNT() get count of unique vehicles and employees
SELECT
a.*,
COUNT(DISTINCT v.vid) AS vehicles,
COUNT(DISTINCT e.eid) AS employees
FROM
`area` a
JOIN vehicle v
ON v.ward_no = a.ward_no
JOIN employee e
ON e.ward_no = a.ward_no
GROUP BY a.name
Related
I encountered a problem on a database I am working with. I have a table of counsels which may hold repeating values, but their is an enrolment number filed which is unique and can be used to fetch them. However, I want to join from a cases_counsel table on the "first" unique value of the counsel table that matches that column on the cases counsel table.
I want to list the cases belonging to a particular counsel using the enrolment_number as the counsel_id on the cp_cases_counsel table. That means I want to pick just a distinct value of a counsel, then use it to join the cp_cases_counsel table and also return the count for such.
However, I keep getting duplicates. This was the mysql query I tried
SELECT T.suitno, T.counsel_id, COUNT(*) as total from cp_cases_counsel T
INNER JOIN (SELECT
enrolment_number as id, MIN(counsel)
FROM
cp_counsel
GROUP BY
enrolment_number
) A
ON A.id = T.counsel_id
GROUP BY T.suitno, T.counsel_id
and
SELECT enrolment_number as id, MIN(counsel) as counsel, COUNT(*) as total FROM cp_counsel
JOIN cp_cases_counsel ON cp_cases_counsel.counsel_id = cp_counsel.enrolment_number
GROUP BY enrolment_number
For the second query, it's joining twice and I am having like double of what I am supposed to get.
The columns that you want in the results are councel (actually only one of all its values) from cp_counsel and counsel_id from cp_cases_counsel, so you must group by them and select them:
SELECT a.counsel, t.counsel_id, COUNT(*) AS total
FROM cp_cases_counsel t
INNER JOIN (
SELECT enrolment_number, MIN(counsel) AS counsel
FROM cp_counsel
GROUP BY enrolment_number
) a ON a.enrolment_number = t.counsel_id
GROUP BY a.counsel, t.counsel_id;
I want to get the each count of data by combining two tables in MySQL. This is the scenario I have following tables. emp_tab(name, dept_id ) and dept_tab(dept_id, dept_name). I want to write a query to show the number of employees in each department with the department name.
tried code:
SELECT dept_tab.dept_name, number
FROM emp_tab
INNER JOIN dept_tab ON emp_tab.dept_id=dept_tab.dept_id;
My try is not successful. Can you please show me how can I solve this. I am beginner to MySQL
Two things:
You need to use a group by and count function
Your join was joining an invalid table
SELECT dept_tab.dept_name, COUNT(*) as number
FROM emp_tab
INNER JOIN dept_tab ON emp_tab.dept_id=dept_tab.dept_id
GROUP BY dept_tab.dept_name
You can use JOIN and GROUP BY by dept_name to count number of employees.
In your question, what is Customerstable? I assume that is dept_tab?
SELECT
d.dept_name,
COUNT(d.id) AS cnt
FROM
dept_tab d
LEFT JOIN empt_tab e
ON e.dept_id = d.dept_id
GROUP BY d.dept_name ;
I have two tables, one is departments and the other is employees. The department id is a foreign key in the employees table. The employee table has a name and a flag saying if the person is part-time. I can have zero or more employees in a department. I'm trying to figure out out to get a list of all departments where a department has at least one employee and if it does have at least one employee, that all the employees are part time. I think this has to be some kind of subquery to get this. Here's what I have so far:
SELECT dept.name
,dept.id
,employee.deptid
,count(employee.is_parttime)
FROM employee
,dept
WHERE dept.id = employee.deptid
AND employee.is_parttime = 1
GROUP BY employee.is_parttime
I would really appreciate any help at this point.
You must join (properly) the tables and group by department with a condition in the HAVING clause:
select d.name, d.id, count(e.id) total
from dept d inner join employee e
on d.id = e.deptid
group by d.name, d.id
having total = sum(e.is_parttime)
The inner join returns only departments with at least 1 employee.
The column is_parttime (I guess) is a flag with values 0 or 1 so by summing it the result is the number of employees that are part time in the department and this number is compared to the total number of employees of the department.
As a preliminary aside, I recommend expressing joins with the JOIN keyword, and segregating join conditions from filter conditions. Doing so would make the original query look like so:
select dept.name, dept.id, employee.deptid, count(employee.is_parttime)
from employee
join dept on dept.id = employee.deptid
where employee.is_parttime = 1
group by employee.is_parttime
It doesn't make much practical difference for inner joins, but it does make the structure of the data and the logic of the query a bit clearer. On the other hand, it does make a difference for outer joins, and there is value in consistency.
As for the actual question, yes, one can rewrite the original query using a subquery or an inline view to produce the requested result. (An "inline view" is technically what one should call an embedded query used as a table in the FROM clause, but some people lump these in with subqueries.)
Example using a subquery
select dept.name, dept.id
from dept
where dept.id in (
select deptid
from employee
group by deptid
having count(*) == sum(is_parttime)
)
Example using an inline view
select dept.name, dept.id
from dept
join (
select deptid
from employee
group by deptid
having count(*) == sum(is_parttime)
) pt_dept
on dept.id = pt_dept.deptid
In each case, the subquery / inline view does most of the work. It aggregates employees by department, then filters the groups (HAVING clause) to select only those in which the part-time employee count is the same as the total count. Naturally, departments without any employees will not be represented. If a list of department IDs would suffice for a list of departments, then that's actually all you need. To get the department names too, however, you need to combine that with data from the dept table, as demonstrated in the two example queries.
in this cust_id is a foreign key and ords returns the number of orders for every customers
SELECT cust_name, (
SELECT COUNT(*)
FROM Orders
WHERE Orders.cust_id = Customers.cust_id
) AS ords
FROM Customers
The output is correct but i want to filter it to retrieve only the customers with less than a given amount of orders, i don't know how to filter the subquery ords, i tried WHERE ords < 2 at the end of the code but it doesn't work and i've tried adding AND COUNT(*)<2 after the cust_id comparison but it doesn't work. I am using MySQL
Use the HAVING clause (and use a join instead of a subquery).....
SELECT Customers.cust_id, Customers.cust_name, COUNT(*) ords
FROM Orders, Customers
WHERE Orders.cust_id = Customers.cust_id
GROUP BY 1,2
HAVING COUNT(*)<2
If you want to include people with zero orders you change the join to an outer join.
There is no need for a correlated subquery here, because it calculates the value for each row which doesn't give a "good" performance. A better approach would be to use a regular query with joins, group by and having clause to apply your condition to groups.
Since your condition is to return only customers that have less than 2 orders, left join instead of inner join would be appropriate. It would return customers that have no orders as well (with 0 count).
select
cust_name, count(*)
from
customers c
left join orders o on c.cust_id = o.cust_id
group by cust_name
having count(*) < 2
I have 3 tables: Emplyees, Jobs and Departments
What I'm trying to achieve is to get the number of emplyees from one department.
I tried something:
SELECT count(Emplyees.id) FROM Emplyees
INNER JOIN Job ON (Job.id = Emplyees.job_id)
INNER JOIN Department ON (Department.id = 2)
but it returns the number of emplyees from all departments.
Any advice please?
An EXISTS clause will allow you to limit by the existence of something without having to worry about whether or not an employee also has other jobs, which will keep your count easy to figure.
Also, since the only thing you need from the department is the id, you can leave that table out and just filter by the dept_id field of the Job table.
SELECT count(id)
FROM Employees
WHERE EXISTS (
SELECT 1
FROM Job
WHERE id = Employees.job_id
AND dept_id = 2
)
Use WHERE clause to filter out department,where clause will apply for the whole result set returned by joins,while condition in on clause will filter result from joined table only
SELECT count(e.id)
FROM Emplyees e
INNER JOIN Job j ON (j.id = e.job_id)
INNER JOIN Department d ON (j.dept_id =d.id )
WHERE d.id = 2
And also use DISTINCT in count so if any employee has applied on multiple jobs that belong to same department will be counted as 1 i.e COUNT(DISTINCT e.id)