Cursor vs standard SQL - sql

I have seen the following question approached to be solved as a cursor although I seen efficiency doing it as a multiple join. How can I solve this via a cursor and should i bother doing so as im extracting it via excel?
RecordID EmpID FirstName LastName HiredDate FiredDate
1111 1 John Flanagan 1/02/2013 1/02/2014
2222 1 Michael Richards 1/01/2014 1/02/2015
3333 3 Peter Johnson 1/08/2014 1/07/2016
4444 3 Jim Crow 1/09/2014 1/02/2017
5555 3 Own Wilson 1/010/2014 1/03/2015
Here's my attempt with SQL initially.
select EmpID, count(RecordID), HiredDate
from Employer
group by EmpID
order by DESC.
Need to write a query that returns each individual employer and for each row include the max employees that were hired by the company and the date of the last hire.
I was asked to write it as a cursor as they wanted to extract the above data line by line from excel.

If EmpId is employer id you are almost there:
SELECT EmpID, COUNT(RecordID), MAX(HiredDate)
FROM Employer
GROUP BY EmpID
ORDER BY EmpID ASC
This will get you the output you require, but I'm not sure what you wanted to order by...I've assumed EmpId.
I've also assumed SQL Server.

Related

Compute number of direct report for each employee in the organization (aggregation)

FYI I use Redshift SQL.
I have a database that looks roughly like the one below (the database has multiple columns that I'll abstract away for simplicity).
This table is a representation of the hierarchical tree within my organization.
employee manager
-------- -------
daniel louis
matt martha
martha kim
laura matt
michael martha
...
As you can see, matt appears in two distinct records, one as the employee and the other as laura's manager. Martha appears in three records, one as an employee and in two other as manager.
I'd like to find a way to compute the number of direct reports each employee has. A conditional count in which the criteria would be where employee = manager, perhaps?
I guess I could find this information using a subquery and then join it back but I was wondering if there was a more "elegant" way to do this making use of window functions maybe.
The expected output for the table above would be:
employee manager direct_reports
-------- ------- --------------
daniel louis 0
matt martha 1
martha kim 2
laura matt 0
michael martha 0
...
I would approach this with a correlated subquery:
select
t.employee,
t.manager,
(select count(*) from mytable t1 where t1.manager = t.employee) direct_reports
from mytable t
This should be a quite efficient method, especially with an index on (employee, manager).
Use a left join and aggregation:
select em.employee, em.manager, count(ew.employee)
from employees em left join
employees ew
on ew.manager = em.employee
group by em.employee, em.manager;

SQL Query to find out all managers and any manager that reports directly to that manager

I have a table demo_snap with columns of employee and supervisor information.
I want to find out all managers and any manager that reports directly to that manager including him/herself.
The query is really confusing me :(
The query which will give the employee and supervisor information is :
Select
employee_number,
first_name e_first_name,
last_name e_last_name,
supervisor_employee_number,
supervisor_first_name,
supervisor_last_name
from demo
Can anybody help me out to mould this query in such a way to find all managers and any manager that reports directly to that manager including him/herself
Sample output of the above query is :
e_number f_name l_name supervisor_e_number s_first_name s_last_name
1 John Smith 2 Adam juan
4 Shree Lekha 2 Adam juan
6 Hema Malini 3 Shruti Hasan
7 Gauri Mikha 1 John Smith
The desired output i want that is i want to create a query such that the following employees are fetched :-
active managers- 2,3 and managers that reports to the active manager-1
The query I have created is :- but this is not giving the desied output
WITH mgr_temp
AS (SELECT person_id mgr_person_id,
employee_number mgr_num,
first_name mgr_name,
supervisor_number mgr_sup
FROM demo mgr
)
SELECT mgrs.mgr_num HISL_ID,
delegs.mgr_num DELEGATE_HISL_ID,
mgrs.mgr_name emp_name,
delegs.mgr_name sup_name
FROM mgr_temp mgrs, mgr_temp delegs
WHERE mgrs.mgr_sup = delegs.mgr_sup
AND mgrs.mgr_num <> delegs.mgr_num

MS Access: Selecting the first item according to a rank

Imagine I have a query called QueryA that returns stuff like this:
Employee Description Rank
John Happy 1
John Depressed 3
James Happy 1
James Confused 2
Mark Depressed 3
I am trying to make a query that grabs the Employee and the Description, but only one description -- the one with the best "rank." (the lower the rank the better). I sort QueryA by Employee then by Rank (descending).
So I'd want my new query QueryB to show that John as Happy, James as Happy, and Mark as Depressed.
However I try selecting Employee and then First of Description and it doesn't always work.
I'm not able to check this for Access, but it should work fine. Check my SQL Fiddle
select
r.employee, d.description
from
table1 as d
inner join (select min(rank) as rank, employee
from
table1
group by employee) r on d.rank = r.rank
and d.employee = r.employee

oracle - sql query select max from each base

I'm trying to solve this query where i need to find the the top balance at each base. Balance is in one table and bases are in another table.
This is the existing query i have that returns all the results but i need to find a way to limit it to 1 top result per baseID.
SELECT o.names.name t.accounts.bidd.baseID, MAX(t.accounts.balance)
FROM order o, table(c.accounts) t
WHERE t.accounts.acctype = 'verified'
GROUP BY o.names.name, t.accounts.bidd.baseID;
accounts is a nested table.
this is the output
Name accounts.BIDD.baseID MAX(T.accounts.BALANCE)
--------------- ------------------------- ---------------------------
Jerard 010 1251.21
john 012 3122.2
susan 012 3022.2
fin 012 3022.2
dan 010 1751.21
What i want the result to display is calculate the highest balance for each baseID and only display one record for that baseID.
So the output would look only display john for baseID 012 because he has the highest.
Any pointers in the right direction would be fantastic.
I think the problem is cause of the "Name" column. since you have three names mapped to one base id(12), it is considering all three records as unique ones and grouping them individually and not together.
Try to ignore the "Name" column in select query and in the "Group-by" clause.
SELECT t.accounts.bidd.baseID, MAX(t.accounts.balance)
FROM order o, table(c.accounts) t
WHERE t.accounts.acctype = 'verified'
GROUP BY t.accounts.bidd.baseID;

Easiest way to find IsManager in SQL

Simple structure table of employees
Employee Manager
Joe Smith Jon Smith
Jon Smith Pete Stevens
Pete Stevens NULL
Jared Scho Pete Stevens
....
Im just trying to return some results but I want an indicator on whether the person is a manager or not so the result should be:
Employee Manager IsAManager
Joe Smith Jon Smith 0
Jon Smith Pete Stevens 1
Pete Stevens NULL 1
Jared Scho Pete Stevens 0
The result set is showing that Joe Smith and Jared Scho are not managers...
So If I had a simple SQL Query
SELECT
Employee,
Manager,
As IsAManager --tried to do a case statement here....
FROM
Employee
I tried to do a case statement something to this effect:
SELECT CASE ISNULL(COUNT(*), 0) > 0 THEN 1 ELSE 0 END FROM Employee WHERE Manager = Employee
Not sure how to word it :)
Hopefully this is just a demo example not your real table structure.
SELECT Employee,
Manager,
CASE
WHEN EXISTS(SELECT *
FROM Employee e2
WHERE e2.Manager = e1.Employee) THEN 1
ELSE 0
END As IsAManager
FROM Employee e1
For details of how SQL Server processes EXISTS Subqueries in CASE Expressions see this article.
To determine whether an employee is a manager, you need to match the Employee's ID (in this case, the name) against the list of Manager IDs (in this case the Manager column). If you find a match, the employee is a manager. If you don't find a match, the employee is not a manager.
You can do this with a LEFT OUTER JOIN as shown here:
SELECT DISTINCT
E.Employee,
E.Manager,
CASE WHEN M.Employee IS NULL THEN 0 ELSE 1 END As IsAManager
FROM
Employee E LEFT OUTER JOIN Employee M
ON E.Employee = M.Manager
Please note the following:
You did not specify the SQL product you're using, so I tried to make the solution general. I'm guessing from your attempt to use ISNULL that it's SQL Server, but this solution should work in any product that supports CASE.
Your method of storing manager status has one problem, which is that you cannot represent a manager with no employees (you derive the manager status from the existence of the employee-manager relationship). If you want to be able to store manager status separately from the employee-manager relationship then CREATE TABLE Managers (Employee. . . PRIMARY KEY). This will make the code necessary to get back manager status a little easier to write as well.