Using aggregate functions in SQL query - mysql

I have my Table structure like this ::
ATT_Table : Fields - Act_ID, Assigned_To_ID, Percent_Complete(Integer value)
Act_ID is primary key, Assigned_To_ID is referenced to Emp_ID in Employee_Table.
Employee_Table : Fields - Emp_ID, F_Name.
Emp_ID is primary key.
Now at a particular point in time, 1 or more activities can be assigned to same person. My goal is write a query to calculate a person's load. I want to count the number of activities assigned to a particular person (can be more than 1) then take the average of their percent_Complete.
For example if person A is assigned A1, A2, A3(Act_ID). Then corresponding (Percent_Complete values addition)/3. Basically an average. In my final query result I want:
Name, Number of activities assigned(Count), load value(Avg).
How do I this? Do I have to use a nested WHERE IN clause ? Thanks.

SELECT MIN(F_Name) Employee_Name ,
COUNT(1) Activities_Assigned ,
AVG(Percent_Complete) Load_Value
FROM ATT_Table a
INNER JOIN Employee_Table e ON a.Assigned_To_ID = e.Emp_ID
GROUP BY e.Emp_ID

I may be missing some nuance, but it sounds like you can just: join the tables, group by employee, COUNT and AVG for the load.

try the following:
select Emp_ID, F_Name, count(Act_ID), avg(Percent_Complete)
from ATT_Table, Employee_Table where ATT_Table.Assigned_To_ID = Employee_Table.Emp_ID
group by Emp_ID, F_Name

As Dmitri said, something like
SELECT Employee_Table.F_Name, COUNT(*) AS activities, AVG(Percent_Complete) AS load
FROM ATT_Table JOIN Employee_Table ON ATT_Table.Assigned_to_ID = Employee_Table.Emp_ID
WHERE Employee_Table.Emp_ID = 42
GROUP BY Employee_Table.Emp_ID

Related

How to get distinct count of rows according to dates

Actually, i did counted distinct empid rows according to dates. But the problem is i get only one empid record of that specific dates.Please let me know how to get all empid records. Here is my sql query.
$sql = "
SELECT COUNT(DISTINCT subcount.empid) AS CountOf
, subcount.name
, subcount.date
, subcount.empid
, calendar.cdate
FROM subcount
, calendar
WHERE subcount.date = calendar.cdate
GROUP
BY subcount.date
";
Here is sql database.
For example, When you look at 2020-11-10 there are two empid with 10 and 7.
When i tried to get both records i get only empid 10 record or 7 record, though i need both record counts:
Here is the output:
Please help me on this.
I think what you are asking is to get list of employees with count of their submissions on a given date, this could show do it:
SELECT cnt.empid AS EmpId
, sc.Name
, cnt.`date` AS Timestamp
, cnt.CountOf AS SubmissionCount
FROM subcount AS sc
INNER JOIN
(
SELECT subcount.empid
subcount.`date`,
count(*) AS CountOf
FROM subcount
INNER JOIN calendar
ON subcount.`date` = calendar.cdate
GROUP BY
subcount.`date`, subcount.empid
) AS cnt
ON sc.empid == cnt.empid
It uses nested SELECT with GROUP BY to calculate count per employee (empid) and date (not only employee). Outer SELECT join nested SELECT to get subcount.Name piece of data which isn't retrieved in nested SELECT so it needs to be retrieved using outer SELECT.
GROUP BY ___ means result rows per ___. If you group by employee ID, you get one row per employee ID. If you want one row per employee ID and date, group by employee ID and date.
SELECT any_value(s.name), s.`date`, s.empid, c.cdate, count(*)
FROM subcount s
JOIN calendar c on c.cdate = s.`date`
GROUP BY s.`date`, s.empid
ORDER BY s.`date`, s.empid;
I expect a calendar table to have one row per date, so there is exactly one cdate for a result row. The name, however, can be different from row to row, so we must tell the DBMS, which to pick. With ANY_VALUE I tell it that I don't care which.

Can and should you loop over query returns from sub-query?

I have a query that returns the employee ID of employees that have a specific skill at a company.
SELECT competences.employee_id
FROM competences
WHERE service_id = 2)
Returns
1
2
4
7
I now want to use this query return to find the names of these employees
from the employees table. I've tried this, which of course didn't work, but can figure out how to do it.
SELECT employee.first_name, employee.last_name
FROM employee
WHERE employee.employee_id =
(SELECT competences.employee_id
FROM competences
WHERE service_id = 2)
How do I use the sub-query to get the employees?
This is a job for JOIN. You should read about JOIN. Many tutorials are available. Here is one.
Try something like this:
SELECT DISTINCT employee.first_name, employee.last_name
FROM employee
JOIN competences ON employee.employee_id = competences.employee_id
WHERE competences.srvice_id = 2
Using IN yields the same results as JOIN. But it uses a so-called dependent subquery, which can be very bad for performance when your tables get large. DISTINCT removes any possible duplicate employee names. If we knew the names and meanings of the columns we could offer more specific advice for generating the most useful query.
You can simply use the IN instead of "="
SELECT first_name, last_name
FROM employee
WHERE employee_id IN (SELECT employee_id
FROM competences
WHERE service_id = 2)
use 'in' instead of equal symbol
SELECT employee.first_name, employee.last_name
FROM employee
WHERE employee.employee_id in
(SELECT competences.employee_id
FROM competences
WHERE service_id = 2)

Selecting count(column) from different table

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

Converting a Join Query into a Sub Query

I'm attempting to write a sub query that wold accomplish the same results as the join query shown below.
SELECT Department_to_major.DNAME
FROM Department_to_major
INNER JOIN Course
ON Department_to_major.Dcode = Course.OFFERING_DEPT
WHERE Course.COURSE_NAME LIKE '%INTRO%'
GROUP BY Department_to_major.DNAME
However each attempt has produced errors.
Is there a way to write this as a sub query?
Hi, You can use below query,
SELECT DNAME FROM Department_to_major WHERE
Dcode IN (SELECT OFFERING_DEPT FROM Course
WHERE COURSE_NAME LIKE '%INTRO%')
You have used GROUP BY clause, but there is no any aggregate function in the query. Is your query works fine?
Here is a way to use a subquery:
SELECT DISTINCT dm.DNAME
FROM Department_to_major dm
WHERE EXISTS (SELECT 1
FROM Course c
WHERE dm.Dcode = c.OFFERING_DEPT AND
c.COURSE_NAME LIKE '%INTRO%'
);
I assume the GROUP BY is to prevent duplicates in the output; SELECT DISTINCT does the same thing.
That said, storing the department code and name in Department_to_major is not a good data structure, because the department name is (presumably) repeated multiple times. I would expect you to have just a Departments table, with one row per department.
Then the query would look like:
SELECT d.DNAME
FROM Departments d
WHERE EXISTS (SELECT 1
FROM Course c
WHERE d.Dcode = c.OFFERING_DEPT AND
c.COURSE_NAME LIKE '%INTRO%'
);
And the SELECT DISTINCT/GROUP BY is unnecessary.
Try the below query. I am assuming that you have used "GROUP BY" clause to make DNAME field unique.
SELECT DISTINCT(DNAME)
FROM Department_to_major
WHERE Dcode IN (SELECT OFFERING_DEPT
FROM Course
WHERE COURSE_NAME LIKE '%INTRO%');

Find all rows with no matching result SQL

I have one table that contains first name and last name of employees in my company, and a field that determines whether they are still working for the company.
I have another table with contains list of tasks for the employees - It also contains two field with first and last name of the employee (- and yes, I know that's not a good structure).
I want to be able to find all employees that are still working for the company but have no tasks using MySQL query.
Any ideas?
SELECT *
FROM employees
WHERE still_working_for_company
AND NOT EXISTS (
SELECT TRUE
FROM tasks
WHERE tasks.firstname = employees.firstname
AND tasks.lastname = employees.lastname
)
You can try this--
select * from FirstTable where firstTable.employee='yes' and
firstTable.empid IN (select secondTbl.empId where firstTable.empid = secondTbl.empId)
Query is not tested and assume that your second table (task table) contain employee data only when task is assign.
Try this:
SELECT e.*
FROM emp e
LEFT JOIN emptask et ON e.firstname = et.firstname AND e.lastname = et.lastname
WHERE e.stillworks = 'y' AND et.taskid IS NULL
GROUP BY e.firstname, e.lastname