group by for Manager and Reps in Employee table - sql

I have a table Employees with Managers and Reps in it. I would want a stored procedure that can get Manager 1 (alphabetic order) and then all Reps under that Manager1 (in alphabetic order) and then Manager 2 and all Reps under the Manager2.
There is a Column 'Manager' for all Employees with EmployeeID of Manager in that column for each Rep and null for Managers. And there is also a column ismanager which will be 1 for Managers and 0 for reps.
I tried doing it but the logic is somewhere incorrect. this is in SQL Server 2005.
Thank you in advance!!
Select * from Employees
groupby IsManager, EmployeeID

What you want to do is order by the manager id and then order by ismanager desc.
Since the manager does not have his own id in the manager column you have use a case statement to fix that. Here are two examples of how to do it in SQL:
WITH fixup AS
(
SELECT CASE MANAGER = 0 THEN EMPLOYEEID ELSE MANAGER END as ManGroup, *
FROM Employees
)
SELECT * from fixup
ORDER BY ManGroup, ismanager DESC
or
SELECT *
FROM Employees
ORDER BY CASE MANAGER = 0 THEN EMPLOYEEID ELSE MANAGER END, ismanager DESC
nb -- not tested might have typos.

select case when isManager=1 then man.name else 'Unmanaged' end as managerName,
emp.name
from employees emp left join employees man on emp.manager = man.employeeId
order by case when isManager=1 then 0 else 1 end,
case when isManager=1 then man.name else 'Unmanaged' end,
emp.name

Related

Optional condition in Oracle 10g

For a dummy test, I want to show a list of employees in a web form.
There is a drop down on the web form that contains a short list of departments, like this:
All Depts
Sales Dept
Marketing Dept
Communication Dept
HR Dept
Finance Dept
IT Dept
The drop down item of All Depts has a value of 0.
The following fiddle shows you what I am trying to do:
http://sqlfiddle.com/#!4/59d1f/2
I know I can do this:
IF (deptid = 0) THEN
select firstname, lastname from employees;
ELSE
select firstname, lastname from employees where deptid = :p_deptid
END IF;
But my real situation has a much more convoluted select query that involves joins of multiple tables. So, I don't wanna clutter up my script with repetitive codes.
Can I achieve my goal using CASE WHEN? Or do I have to use dynamic SQL?
Thanks.
SELECT firstname, lastname
FROM employees
WHERE 0 = :p_deptid
OR dept_id = :p_deptid

How to keep a bucket using case statement even if the count for items in that bucket is 0?

Here's the data table named "Salary_table" that i've created for this question:
So I want to find the number of employees in each salary bucket in each department. the buckets are
"<$100" "$100-$200" and ">$200"
The desired output is:
Below is my code for achieving this task:
select distinct(st.department) as "Department",
sb.salary_bucket as "salary range", count(*)
from Salary_table st
Left join (
select department, employee, case
when salary < 100 then "<$100"
when salary between 100 and 200 then "$100-$200"
else ">$200"
end
as salary_bucket
from Salary_table
) sb
on sb.employee = st.employee
group by st.department, sb.salary_bucket
order by st.department, sb.salary_bucket
;
but my output is a bit short of what im expecting:
There are TWO problems with my current output:
The buckets with 0 employees earning the salary in the bucket range are not listed; I want it to be listed with a value "0"
The salary bucket is NOT in the right order, even though I added in the statement "order by" but I think it's b/c its texts so can't really do that.
I would really appreciate some hints and pointers on how to fix/achieve these two issues I've addressed above. Thank you so much!
what i've tried
I tried use "left join" but output came out the same
I tried adding the "order by" clause but doesnt seem to work on text buckets
You are sort of on the right track, but the idea is a bit more complicated. Use a cross join to get all the rows -- the buckets and departments. Then use left join to bring in the matching information and finally group by for the aggregation:
select d.department, b.salary_bucket,
count(sb.department) as cnt
from (select '<$100' as salary_bucket union all
select '$100-$200' union all
select '>$200'
) b cross join
(select distinct department from salary_table
) d left join
(select department, employee,
(case when salary < 100 then '<$100'
when salary between 100 and 200 then '$100-$200'
else '>$200'
end) as salary_bucket
from Salary_table
) sb
on sb.department = d.department and
sb.salary_bucket = b.salary_bucket
group by d.department, b.salary_bucket;

Conditional Select statemtn

Using the AdventureWorks database, I need to produce a list of job titles and the amount of employees who are assigned to each of them. But that's not my concern.
When the OrganizationLevel is 2 or below, I need to make the Job Title field capitalized. However, I also need a condition that restricts job titles from being displayed when they're 3 or below. Can you please help me? Here is an (incorrect) attempt - I'm aware this is wrong, I've practically given up, but I'm hopeful it will help explain what I'm trying to achieve here.
SELECT distinct JobTitle, count(JobTitle) as CountOf from HumanResources.Employee
WHERE (OrganizationLevel < 3)
GROUP BY JobTitle
ELSE IF (OrganizationLevel < 2) select distinct UPPER(JobTitle);
SELECT
CASE
WHEN OrganizationLevel < 2 THEN JobTitle
ELSE UPPER(JobTitle)
END as JobTitle,
count(*) as CountOf
FROM HumanResources.Employee
WHERE OrganizationLevel < 3
GROUP BY
CASE
WHEN OrganizationLevel < 2 THEN JobTitle
ELSE UPPER(JobTitle)
END

How To Get Column Description

For example, in a [emp] table, the columns are :
emp_id emp_name emp_role
If the values being inserted in emp_role column values can be 0 (for Administrator), 1 (for Management), 2 (for Employees).
Now is there any way to get those details of a column emp_role (like, 0 for Administrator) along with the table concerned (i.e, [emp]) in SQL server database ?
Thanks.
If you have dictionary table with role definitions it will be something similar to:
select e.emp_id, e.emp_name, r.name
from emp e
inner join role r on e.emp_role = r.id
if not, but you know role names it will be something similar to:
select emp_id, emp_name,
case emp_role when 0 then 'Administrator' when 1 then 'Management' when 2 then 'Employees' end as RoleName
from emp

SQL question: How can I extract this information from these tables?

I have these 3 tables:
EMPLOYEES
Emp_id PK || First_Name || Last_Name || Hiring_Date
Department
Dep_Name || emp_id
SALARIES
salary || emp_id
Two months ago, the company hired new employees.
I need to write a SQL statement, that counts how many employees were hired. In the SAME statement, I need to find out, what are the financial increases by each department, after the new hirings.
For the first thing, I think this is the query:
SELECT COUNT(emp_id) FROM employees
WHERE YEAR(NOW()) - YEAR(hiring_date) = 0 AND (MONTH(NOW()) - MONTH(hiring_date) = 2 OR MONTH(NOW()) - MONTH(hiring_date) = - 2);
but, I don't know how can I extract the information for the 2nd thing. (I know I need to make a join, but I don't know how to extract the increases by each department)
Once again, the 1st and 2nd must be IN THE SAME SQL STATEMENT.
This variant needs all three tables. It uses Standard SQL interval notations; not many DBMS actually support it, but this works when the current date is in January and the question's version does not:
SELECT Dep_Name, COUNT(*), SUM(SALARY)
FROM Employees AS E NATURAL JOIN Salaries AS S ON E.Emp_ID = S.Emp_ID
NATURAL JOIN Department AS D ON E.Emp_ID = D.Emp_ID
WHERE CURRENT_DATE - Hiring_Date <= INTERVAL(2) MONTH
GROUP BY Dep_Name;
I note that the Department table is a little unusual - more normally, it would be called something like Department_Emps; as it stands, its primary key is the Emp_ID column, not the Dep_Name column.
[For the record, the query below is what I used with IBM Informix Dynamic Server.]
SELECT Dep_Name, COUNT(*), SUM(SALARY)
FROM employees AS E JOIN salaries AS S ON E.Emp_ID = S.Emp_ID
JOIN department AS D ON E.Emp_ID = D.Emp_ID
WHERE CURRENT YEAR TO DAY <= INTERVAL(2) MONTH TO MONTH + Hiring_Date
GROUP BY Dep_Name;
SELECT COUNT(emp_id), SUM(salary)
FROM employees e JOIN salaries s ON (s.emd_id = e.emp_id)
WHERE YEAR(NOW()) - YEAR(hiring_date) = 0
AND (MONTH(NOW()) - MONTH(hiring_date) = 2
OR MONTH(NOW()) - MONTH(hiring_date) = - 2)