sql show current instance - sql

here is the assignment that I had to face:
List the employees who have transferred between departments during their employment. You should show their current department, and the date when the transferred to the current department. This is a pretty tough query. My solution was to use a subquery to determine which employees have been in more than one department, and use that result in the base query.
The problem that I don't know how to display the employee who have been transfered and only once. The way to tell if the employee has been transfered is if in the EmployeeDepartmentHistory table, the employee id has been in more than one record (i.e. employeeID 1 is in both record 1 and record 2 because the person has been in two departments). How would I go about this? Here's what I have as of now:
SELECT EmployeeDepartmentHistory.EmployeeID,Person.Contact.FirstName, Person.Contact.LastName, Department.Name
From HumanResources.Department INNER JOIN
HumanResources.EmployeeDepartmentHistory ON
HumanResources.Department.DepartmentID =
HumanResources.EmployeeDepartmentHistory.DepartmentID INNER JOIN
HumanResources.Employee ON HumanResources.EmployeeDepartmentHistory.EmployeeID
= HumanResources.Employee.EmployeeID INNER JOIN
Person.Contact ON HumanResources.Employee.ContactID = Person.Contact.ContactID
WHERE EmployeeDepartmentHistory.EmployeeID=(SELECT COUNT(HumanResources.EmployeeDepartmentHistory.EmployeeID)
FROM HumanResources.EmployeeDepartmentHistory
WHERE EmployeeDepartmentHistory.EmployeeID = Employee.EmployeeID
Group by EmployeeDepartmentHistory.EmployeeID)

Not sure if I get the requirement correct. Would you want to try HAVING clause at the end?
That is:
HAVING COUNT(EmployeeDepartmentHistory.EmployeeID) = 2
(2 - assuming that the EmployeeDepartmentHistory will contain the current department as well)

Related

Getting a selection from multiple tables using JOIN

There is a task: Display the hourly rates of employees, indicating the maximum rate for each department in the column Max In Department. Within each department, divide all bets into groups so that bets with the same values are part of the same group.
I wrote a request to get a breakdown of bids into groups in departments, and I ran into the problem that the maximum bid in the department is calculated by the column with the breakdown of the bid per group, but it is necessary by departments, I tried both through a separate request and a connection with this and through a nested query, I can't understand what I'm doing wrong
I will be grateful for any help!
SELECT Name AS DepartmentName
, Rate AS GroupOfRate
, MAX(eph.Rate) AS MaxRateInDepartment
FROM HumanResources.EmployeeDepartmentHistory edh
INNER JOIN HumanResources.Department d
ON edh.DepartmentID = d.DepartmentID
INNER JOIN HumanResources.EmployeePayHistory eph
ON edh.BusinessEntityID = eph.BusinessEntityID
GROUP BY Name
, Rate
The first photo is the result of my request with an error. The second photo, the tables on which the selection is made (1 table EmployeePayHistory, where the employee rates are located; 2 table EmployeeDepartmentHistory; 3 table just take the names of departments). The third photo, as it should turn out (made in Paint)
Photo #1
Photo #2
Photo #3
One possible way is to add a partition.
SELECT Name AS DepartmentName
, Rate AS GroupOfRate
, MAX(eph.Rate) OVER ( PARTITION BY Name ORDER BY Name ) AS MaxRateInDepartment
FROM HumanResources.EmployeeDepartmentHistory edh
INNER JOIN HumanResources.Department d
ON edh.DepartmentID = d.DepartmentID
INNER JOIN HumanResources.EmployeePayHistory eph
ON edh.BusinessEntityID = eph.BusinessEntityID
GROUP BY Name
, Rate
By grouping by rate, you're restricting your MAX to Department Name and Rate. The OVER clause frees it up to look only at the department name.
You can confirm by adding an ORDER BY clause to the query.
ORDER BY Name
, Rate
This should show that the first row for each department matches the department maximum.
Your GROUP BY Name, Rate clause will create separate groups for each distinct department name and rate, which means every rate within that group will be the same. That is why Max(Rate) is giving you the same value as Rate.
If you need to display individual rates and "max rate per department" on the same line, you can use a window function. SQL window functions can be thought of as defining their own scope separate from GROUP BY. In your case you want to drop the GROUP BY and calculate the MAX rate partitioned by department.
Search for "SQL window function" for more information, syntax, and examples.

Using two self joins to find the subordinates of managers' subordinates

So let's say I have a table that includes employees and their direct supervisor (as denoted by parentEmployeeKey). How do I return the number of subordinates of a given employee, as well as how many subordinates are underneath their subordinates (indirect subordinates). This is kind of what I would imagine the code looking like, but I know there are issues.
SELECT
Employee.EmployeeKey,
COUNT(Employee_1.EmployeeKey,
COUNT(Employee_2.EmployeeKey)
FROM
Employee
INNER JOIN
Employee AS Employee_1 ON Employee_1.ParentEmployeeKey = Employee.EmployeeKey
INNER JOIN
Employee AS Employee_2 ON Employee_2.ParentEmployeeKey = Employee1.EmployeeKey
WHERE
Employee.blahblah is blahblah
GROUP BY
blah blah blah
Thank you!
Well, here's an example using the form you chose (joins). Just a couple of adjustments needed.
COUNT should be DISTINCT to protect against JOIN behavior. The second count doesn't really need it in this case.
JOINs are now LEFT outer joins, so we don't lose results that have no subordinates and maybe a little more importantly, those with no sub-subordinates.
If you really wanted only those with at least 1 subordinate, the first JOIN could have been an INNER JOIN.
Just add the two counts to obtain the total subordinates and sub-subordinates.
-- Proposed SQL, in the requested form (joins)
SELECT Employee.EmployeeKey
, COUNT(DISTINCT Employee_1.EmployeeKey) AS subordinates
, COUNT(DISTINCT Employee_2.EmployeeKey) AS subsubordinates
FROM Employee
LEFT JOIN Employee AS Employee_1 ON Employee_1.ParentEmployeeKey = Employee.EmployeeKey
LEFT JOIN Employee AS Employee_2 ON Employee_2.ParentEmployeeKey = Employee_1.EmployeeKey
GROUP BY Employee.EmployeeKey
;
The test case:
Test case for sql-server

SQL Query - select name with max projects and least projects

I need to create a query that displays the Manager and Department name for the Department with the most number projects and least number of projects based on this database scheme. I can't figure out how to determine the most amount and least amount of projects.
Database Scheme
I'd start by joining together any needed data. You're going to need Manager name, so we'll need to join the employee table.
SELECT
e.fname, d.dname
FROM
department d
LEFT JOIN
employee e ON e.ssn = d.mgr_ssn
LEFT JOIN
(SELECT
department.dnumber, COUNT(*) [projects]
FROM
department
LEFT JOIN
project on department.dnumber = project.dnum
GROUP BY
department) total ON d.dnumber = total.dnumber
HAVING
total.projects = MAX(total.projects)

Joining two tables in SQL Server when one table has huge data and other has few data

If I want to join two tables (not inner join), Left table has huge data (millions of record), and right table has few records. What should I prefer (Left or Right Outer join) and why.
Well first of all That join is independent of the size of the tables
Well I think this depends what data you want either from Left table or from right table let us assume you have two tables Employees which has millions of records let us put this in right and Department which has 10 record put it in left Now each employee has one department.
Employee
EmpID
DepartmentId
Department
DepartmentId
Department Name
Now Suppose You want to know which employee belongs to which Department Use This Query.
Select e.empId,d.DepartmentName
from employee e
join department d
on e.departmentid=d.departmentid
Now Suppose You want to know which employee has now assigned any department
use the below query
Select e.empId,d.DepartmentName
from employee e
left join department d
on e.departmentid=d.departmentid
where d.departmentid is null
Now Suppose You want to know how many employees which depratment use the below query
Select d.[Department Name],COUNT(e.empID) from Employee e
left join Department d
on e.DepartmentId=d.DepartmentId
group by d.[Department Name]
For more information about joins please use the below image

How do I join 3 tables using mysql

I have the following tables:
TABLE: companies c
FIELDS: id, name, description
TABLE: departments d
FIELDS: id, name, description
TABLE employees e
FIELDS: id, company_id, department_id, name
I'm trying to get a list of all employees for company 1 and also get the department name (d.name) into the results of the row.
Here's my original query:
SELECT e.*, c.name as company
FROM employees e, companies c
WHERE e.company_id=c.id AND e.company_id=1;
What should I add to this query to get the department name (d.name) to appear in each row of the query? Also... e.department_id may be equal to 0 in some cases since there are no departments for a specific company.
Thanks for the help everyone!
SELECT e.id, e.name, e.department_id, c.name, d.name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
LEFT JOIN companies AS c ON e.company_id = c.id
WHERE e.company_id = 1;
Generally you can mix-match joins in any order, as long as any columns/tables you require in a join have already been joined previously. In this case, you're slurping up data from two separate tables that are related via the employees data, and neither of them are co-dependent, so you can order the two LEFT JOIN lines in any order.
As well, with a LEFT join, you get all rows from the table on the "left" side of the join (in this case, the employees table) and matching rows (if any) from the right table (companies/departments). If there's no matching rows in either companies or departments, then any columns coming from those tables will be NULL in the result set.