SQL with group count - sql

This is simple table and I have issue with group count.
STUID DEPT
100 Math
100 History
200 Math
200 History
This is my query
select count (distinct(STUID)), DEPT
from table
group by DEPT
and outcome count 2 for Math, 2 for History.
I need count without duplicate for STUID so the outcome look like
STUID DEPT
1 Math
1 History
My goal is to count stuid ( no dup ) group by Dept

I need count without duplicate for STUID
You query does that already: it counts each stuid just once, even if it appears multiple times for a given department. For example, if you had the following dataset, you would still get the same result (that is, a count of two for each department:
STUID DEPT
100 Math
100 History
200 Math
200 History
100 Math
100 History
200 Math
200 History
If you just want the distinct dept values, use distinct - we could add literal 1 to each row, but it wouldn't be very helfpul:
select distinct dept from mytable

Related

Join results of two queries in SQL and produce a result given some condition

I've never used SQL until now, so please bear with me. I have a table of departments:
I have written two queries as follows:
-- nbr of staff associated with each dept.
SELECT count(departmentId) as freq
FROM staff
GROUP BY departmentId
-- nbr of students associated with each dept.
SELECT count(departmentId) as freq
FROM StudentAssignment
GROUP BY departmentId
These produce the following two tables:
For each department id 1 to 5, I need to divide the studentFreq by the staffFreq and show the department id and description if the result is greater than 2.
If the staffFreq i.e. number of staff, for a department id is zero then I need to show that department id and description too.
So for example, in this case I want to produce a table with the department ids of 1, 4 and 5 and their corresponding descriptions: Computing, Classics and Mechanical Engineering.
Computing because 7 / 2 > 2. Classics and ME because 0 staff are assigned to those depts.
One method is a left join, starting with the departments table:
SELECT d.*,
s.freq as as num_staff, sa.freq as num_students,
sa.freq * 1.0 / s.freq as student_staff_ratio
FROM deptartments d LEFT JOIN
(SELECT departmentId, count(*) as freq
FROM staff
GROUP BY departmentId
) s
ON s.departmentId = d.department_id LEFT JOIN
(SELECT departmentId, count(*) as freq
FROM StudentAssignment
GROUP BY departmentId
) sa
ON sa.departmentId = d.departmentId;
Notes:
This should missing values as NULL rather than 0. You can assign 0 instead using COALESCE(): COALESCE(s.freq, 0) as num_staff.
SQL Server does integer division, so 7 / 2 = 3, not 3.5. I think you would typically want the fractional component.

SQL - result in one record

I am new to SQL (first time) and I try to get my result in 1 record:
I have a table with 3 entries: city_name, company_name, and employee number
Basically, in my table I have a company which repeats 2 times: city_name: Rome, company_name: ABC, employee number: 100 --> this entry is 2 times in the table
How can I make this 2 entries to be shown in the table as a single record and to sum my employee numbers. I need that 2x100 empolyee to be in a single shown as 200? So I will have something like this:
city_name company_name employee
Rome ABC 200
You are describing group by:
select city_name, company_name, sum(empoyee_number)
from t
group by city_name, company_name

Need to count the filtered employees

I wrote a query which need filter out the employee data on behalf on their employee codes.
For instance, in my XYZ table i have 200 employees, i need to insert these 200 employee in ABC table, but before inserting, i need to check whether all 200 employees are existed in the system,I first filter out the employee and then insert into my ABC table.
suppose, 180 out of 200 employee matched, then i will insert 180 in the ABC table.
Now i want the count 200-180=20, so i need that difference count.
I wrote a query but it fetches only the matched record, not those employee count who filters out.
Select distinct SD.EMP_code
FROm SALARY_DETAIL_REPORT_012018 SD /*219 Employees*/
JOIN
(SELECT * FROM EMPLOYEE) tbl
ON tbl.EMP_CODE=to_char(SD.EMP_CODE)
WHERE SD.REFERENCE_ID like '1-%';
final output : 213 employees
I want 219-213=6
i want those 6 employees. I also tried INTERSECT but i got same result.
Select distinct to_char(SD.EMP_code)
FROm SALARY_DETAIL_REPORT_012018 SD
WHERE SD.REFERENCE_ID like '1-%'
INTERSECT
SELECT EMP_CODE FROm EMPLOYEE;
OUTPUT
213 Employees
Kindly help me to find out the count of filtered employees
You can use NOT EXISTS :
SELECT DISTINCT SD.EMP_code
FROM SALARY_DETAIL_REPORT_012018 sd
WHERE NOT EXISTS (SELECT 1 FROM EMPLOYEE e WHERE e.EMP_CODE = TO_CHAR(SD.EMP_CODE)) AND
SD.REFERENCE_ID LIKE '1-%';
use except opertaor
Select distinct to_char(SD.EMP_code)
FROM SALARY_DETAIL_REPORT_012018 SD
WHERE SD.REFERENCE_ID like '1-%'
except
SELECT EMP_CODE FROm EMPLOYEE;

Eliminate NULL records in distinct select statement

In SQL SERVER 2008
Relation : Employee
empid clock-in clock-out date Cmpid
1 10 11 17-06-2015 001
1 11 12 17-06-2015 NULL
1 12 1 NULL 001
2 10 11 NULL 002
2 11 12 NULL 002
I need to populate table temp :
insert into temp
select distinct empid,date from employee
This gives all
3 records since they are distinct but what
I need is
empid date CMPID
1 17-06-2015 001
2 NULL 002
Depending on the size and scope of your table, it might just be more prudent to add
WHERE columnName is not null AND columnName2 is not null to the end of your query.
Null is different from other date value. If you wont exclude null record you have to add a and condition like table.filed is not null.
It sounds like what you want is a result table containing a row or tuple (relational databases don't have records) for every employee with a date column showing the date on which the worked or null if they didn't work. Right?
Something like this should do you:
select e.employee_id
from ( select distinct
empid
from employee
) master
left join employee detail on detail.empid = master.empid
and detail.date is not null
The master virtual table gives you the set of destinct employees; the detail gives you employees with non-null dates on which they worked. The left join gives you everything from master with any matches from detail blended in.
Rows in master with no matching rows in details, are returned once with the contributing columns from detail set to null. Rows in master with matching rows in detailare repeated once for each such match, with the detail columns reflecting the matching row's values.
This will give you the lowest date or null for each empid
SELECT empid,
MIN(date) date,
MIN(cmpid) cmpid
FROM employee
GROUP BY empid
try this
select distinct empid,date from employee where date is not null

group by in sql to find max count

Update
I have a query like this
select sl.College_ID,sl.Department_ID,COUNT(sl.RegisterNumber) from StudentList sl
group by sl.College_ID,sl.Department_ID
order by sl.College_ID,sl.Department_ID asc
abouve query gives the below result
and i have 200 - college id and each college have 6 department_id i could get the count [No.of student ] in each department
College_Id Dept_Id count
1 1 100
1 2 210
2 3 120
2 6 80
3 1 340
but my question is i need to display the maximum count[student] for each department
some thing like this
college_ID Dept_Id count
3 1 340
26 2 250
and i tried this out but getting error
select sl.College_ID,sl.Department_ID,COUNT(sl.RegisterNumber) from StudentList sl
group by sl.College_ID,sl.Department_ID
having COUNT(sl.RegisterNumber)=max(COUNT(sl.RegisterNumber))
order by sl.College_ID,sl.Department_ID asc
what went wrong can some one help me
Maybe something like this?
SELECT sl.College_ID, sl.Department_ID, COUNT(sl.RegisterNumber) As StudentCount, s2.MaxCount
FROM StudentList sl
INNER JOIN (
SELECT Department_ID, MAX(StudentCount) AS MaxCount
FROM (
SELECT College_ID, Department_ID, COUNT(*) As StudentCount
FROM StudentList
GROUP BY College_ID, Department_ID
) s1
GROUP BY Department_ID
) s2 ON sl.Department_ID = s2.Department_ID
GROUP BY sl.College_ID, sl.Department_ID, s2.MaxCount
HAVING COUNT(sl.RegisterNumber) = s2.MaxCount
ORDER BY sl.College_ID, sl.Department_ID ASC
EDIT: I've updated the query to more accurately answer your question, I missed the part where you want the College_ID with the max count.
EDIT 2: Okay, this should work now, I needed a second nested subquery for aggregating the aggregates. I don't know of a better way to compare the aggregates of different groups.
The result you want, which is group on college_ID and you not really care about college_ID, since from you example, with Dept_Id=1 will can not sure which college_ID is.
In that case, you can remove college_ID from your select statement and do a SUM GROUP BY
base on your query, something like:
SELECT t.Department_ID, SUM(t.c)
FROM (
select sl.College_ID,sl.Department_ID,COUNT(sl.RegisterNumber) c from StudentList sl
group by sl.College_ID,sl.Department_ID
) t
GROUP BY t.Department_ID
ORDER BY SUM(t.c)
Note: If you really want college_ID in your result, you can do a JOIN to get your college_ID