How to exclude general criteria value from group by - sql

I have two tables :
One for employees data Employee
Another for employee vacations balance VacBal
Now i want to get the current vacation balance for each employee,considering if the emp_num = 0 then it's a general balance for all employees not for specific employee
If Employee table Sample data like that :
emp_num name
546 john
134 Ramy
and
VacBal like that
emp_num bal_num bal_date
546 1 5-5-2015
546 2 6-5-2015
134 1 7-5-2015
0 3 2-2-2015
0 4 6-1-2015
I want result set like this :
emp_num name SUM(bal_num)
546 john 10 --->3+7
134 Ramy 8 --->1+7
How to do this ?

You can use a correlated sub-query to SUM:
select e.emp_num, e.name, (select sum(vb.bal_num) from VacBal vb
where vb.emp_num in (e.emp_num,0))
from Employee e

SELECT e.emp_num,
name,
Sum(bal_num) + (SELECT Sum(bal_num)
FROM vacbal vb
WHERE emp_num = 0)
FROM employee e
inner join vacbal v on e.emp_num=v.emp_num
GROUP BY e.emp_num,
name

Related

Displaying columns as rows SQL

I have the below tables:
Corporate table:
CorporateId DirectorId ManagerId SalesId
1 1 1 1
2 2 2 3
3 3 4 5
Employee table:
EmployeeId FirstName LastName
1 Tim Sarah
2 Tom Paulsen
3 Tam Margo
4 Eli Lot
5 Ziva Lit
I want to display, for one corporate,the names of the Director, Manager and Sales in rows. Example with corporate 3:
EmployeeId FirstName LastName
3 Tam Margo
4 Eli Lot
5 Ziva Lit
How can I do that? I know how to display rows as columns using pivot, but unsure if pivot can be used here also.
Any help please?
You may join the two tables as the following:
SELECT E.EmployeeId, E.FirstName, E.LastName
FROM Employee E JOIN Corporate C
ON E.EmployeeID IN (C.DirectorId ,C.ManagerId ,C.SalesId)
WHERE C.CorporateId=3
See a demo.
You can first un-pivot your rows into columns by using cross apply, after which you simply join the pivoted rows to your employee table:
select e.*
from corporate c
cross apply (
select EmployeeId from (
values (Directorid), (ManagerId), (SalesId)
)r(EmployeeId)
)r
join employee e on e.EmployeeId = r.EmployeeId
where c.CorporateId = 3;

Removing duplicates by adding them up [SQL]

I have a query like this:
select employee_id, salary
from salary
left join employee on salary.employee_id=employee.id_employee;
It returns me these results
EMPLOYEE ID | SALARY
-------------|-------
1 | 50
2 | 50
3 | 50
1 | 30
How do I remove duplicates by adding them up, like this:
EMPLOYEE ID | SALARY
------------|--------
1 | 80
2 | 50
3 | 50
There is no reason for a left join from salary to employee. Presumably, every employee_id in salary refers to a valid employee. So, this should do what you want:
select s.employee_id, sum(s.salary) as salary
from salary s
group by s.employee_id;
If you want all employees, even those who are not in the salary table, then an outer join is appropriate -- but employee should be first:
select e.id_employee, sum(s.salary) as salary
from employee e left join
salary s
on s.employee_id = e.id_employee
group by e.id_employee;
Employees not in salary will have a value of NULL.
Note that the group by condition in this query is on employee, the first table in the left join.
select employee_id, SUM(salary) as salary
from salary
left join employee on salary.employee_id=employee.id_employee
group by emplyee_id;
This is exactly what a group by clause is for. You'll have to group by the emplopyee_id and specify how you want to aggregate the salary:
SELECT employee_id, SUM(salary)
FROM salary
GROUP BY employee_id

Finding second highest record from a table

I want to find salary and the employees name from employee table.This employee table have column like emp_id, emp_name, emp_salary. To be clear:
emplyee
--------------
| emp_id|emp_name|emp_salary|
-----------------------------
| 100 |John | 2500 |
| 200 |Nash | 1500 |
| 300 |Koffe | 100 |
| 400 |Anan | 6000 |
| 500 |Moon | 2600 |
-----------------------------
From the above table second highest salary is 2600. How can I find this?
You can try:
SELECT max(salary)
FROM emptable
WHERE salary < (SELECT max(salary)
FROM emptable);
we can achieve this one in correlated sub query
select e1.emp_ename,e1.emp_salary from employee e1
where 2=(select count(distinct e2.emp_salary) from employee e2 where e2.salary>=e2.salary);
see how it works
select * from employees
emp_id emp_ename emp_salary
1 naresh 100
2 suresh 150
3 mahesh 200
4 sai 250
in the above table second highest salary is 200
correlated sub query means first parent query is executed first then child query is executed
see how this query is working
select e1.emp_ename,e1.emp_salary from employee e1
where 2=(select count(distinct e2.emp_salary) from employee e2 where e2.salary>=e2.salary);
1st step: first row sal goes to child query where clause
select e1.emp_ename,e1.emp_salary from employee e1
where 2=(select count(distinct e2.emp_salary) from employee e2 where e2.salary>=100)
so it counts how rows greater than 100(i.e=4)
so condition false
select e1.emp_ename,e1.emp_salary from employee e1
where 2=4(false)
2nd step
select e1.emp_ename,e1.emp_salary from employee e1
where 2=(select count(distinct e2.emp_salary) from employee e2 where e2.salary>=150);
select e1.emp_ename,e1.emp_salary from employee e1
where 2=3(FALSE)
3r step
select e1.emp_ename,e1.emp_salary from employee e1
where 2=(select count(distinct e2.emp_salary) from employee e2 where e2.salary>=200);
select e1.emp_ename,e1.emp_salary from employee e1
where 2=2(TRUE)
SO FINAL WE GOT 200
I HOPE IT WELL USE FULL FOR YOU ALL THE BEST

sql query for getting data from two related tables

I have two tables, employee and inventory. One employee can have zero or more inventories.
I would like to list employee information along with at most one inventory information
and count of inventories belongs to one employee.
employee table
emp_num last_name first_name
-----------------------------------
100 john smith
101 mike pet
102 jes lyoid
inventory table
inv_num emp_num
---------------------------
12 100
13 100
15 100
30 102
desired Output
emp_num last_name invnum count(inv_num)
--------------------------------------------------------------------------
100 john 12 3
101 mike - 0
102 jes 30 1
What sql query can I use in this case?
Try this:
SELECT emp_num, last_name, MAX(inv_num) AS invnum, COUNT(inv_num) AS inv_count
FROM employee e LEFT OUTER JOIN inventory i ON e.emp_num = i.emp_num
GROUP BY e.emp_num, e.last_name
You could do something like this
Select E.Emp_Num,
e.Last_name,
MIN(Inv_Num) AS OldestInv,
COUNT(Inv_Num) AS TotalInv
FROM Employee E
LEFT OUTER JOIN Inventory I
(E.Emp_Num = I.Emp_Num)
GROUP BY E.Emp_Num, E.Last_Name
This will give you the minimum invoice number and the total count. The left outer join is the key
SELECT
e.emp_num,
e.last_name,
IFNULL(MAX(i.inv_num),'-') AS 'invnum',
COUNT(i.inv_num) AS 'count(inv_num)'
FROM
employee e LEFT JOIN inventory i
ON e.emp_num = i.emp_num
GROUP BY
e.emp_num, e.last_name

select dept names who have more than 2 employees whose salary is greater than 1000

How would do the following in SQL
"select dept names who have more than 2 employees whose salary is greater than 1000" ?
DeptId DeptName
------ --------
1 one
2 two
3 three
EmpId DeptId Salary
----- ------ ------
121 1 2000
122 1 2000
123 1 5000
124 1 4000
131 2 2000
132 2 6000
133 2 1000
134 2 1000
125 3 1000
126 3 20000
RESULT: one
How about something like this?
SELECT D.DeptName FROM
Department D WHERE (SELECT COUNT(*)
FROM Employee E
WHERE E.DeptID = D.DeptID AND
E.Salary > 1000) > 2
SELECT DEPTNAME
FROM(SELECT D.DEPTNAME,COUNT(EMPID) AS TOTEMP
FROM DEPT AS D,EMPLOYEE AS E
WHERE D.DEPTID=E.DEPTID AND SALARY>1000
GROUP BY D.DEPTID
)
WHERE TOTEMP>2;
select min(DEPARTMENT.DeptName) as deptname
from DEPARTMENT
inner join employee on
DEPARTMENT.DeptId = employee.DeptId
where Salary > 1000
group by (EmpId) having count(EmpId) > =2
hope this helps
select DeptName from DEPARTMENT inner join EMPLOYEE using (DeptId) where Salary>1000 group by DeptName having count(*)>2
select D.DeptName from [Department] D where D.DeptID in
(
select E.DeptId from [Employee] E
where E.Salary > 1000
group by E.DeptId
having count(*) > 2
)
select deptname from dept_1
where exists
(
SELECT DeptId,COUNT(*)
FROM emp_1
where salary>1000
and emp_1.deptid=dept_1.deptid
GROUP BY DeptId
having count(*)>2)
1:list name of all employee who earn more than RS.100000 in a year.
2:give the name of employee who earn heads the department where employee with employee I.D
My main advice would be to steer clear of the HAVING clause (see below):
WITH HighEarners AS
( SELECT EmpId, DeptId
FROM EMPLOYEE
WHERE Salary > 1000 ),
DeptmentHighEarnerTallies AS
( SELECT DeptId, COUNT(*) AS HighEarnerTally
FROM HighEarners
GROUP
BY DeptId )
SELECT DeptName
FROM DEPARTMENT NATURAL JOIN DeptmentHighEarnerTallies
WHERE HighEarnerTally > 2;
The very early SQL implementations lacked derived tables and HAVING was a workaround for one of its most obvious drawbacks (how to select on the result of a set function from the SELECT clause). Once derived tables had become a thing, the need for HAVING went away. Sadly, HAVING itself didn't go away (and never will) because nothing is ever removed from standard SQL. There is no need to learn HAVING and I encourage fledgling coders to avoid using this historical hangover.