A strange way of writing query encountered - sql

This may seems the most dumbest question ever on stackoverflow but I am just wondering why would you write such a query:
Select e1.Emploee_ID, e1.Departement_ID From Employee e
Inner join Employee E1 on e.employee_id= e1.Employee_ID
Inner join Departement d on d.dep_id= e1.departement_id
Why do we have to join on employee? my obvious query would be
select e.employee_ID, e.Departement_id from employee e
inner join Departement d on d.dep_id= e1.departement_id

Referencing the PK with an inner join is redundant.
You would normally join on the same table to link with another record, for example if you have a FK-column that reference the boss of an employee.
Assuming you would have a nullable foreign-key column Boss_ID in table Employee
Select e.Employee_ID, boss.Employee_id, d.Departement_ID
From Employee e
LEFT OUTER JOIN Employee boss on boss.Employee_ID=e.Boss_ID
INNER JOIN Departement d on d.dep_id= e.departement_id
Note that i've used a LEFT OUTER JOIN to get also the employee that have no bosses.

What I can see. You do not need this join.
Inner join Employee E1 on e.employee_id= e1.Employee_ID
The two queries will give the same result. I can not see the point of JOINing twice on the Employee table.

I can't see any reason to join Employee to Employee in this query. In the past I've occasionally used two subsets of the same table in the same query, but there's nothing like that going on here. To me it looks like this was done by mistake.

If employee_id is a PK then it doesn't make sense, but if it is not the two queries will return different results.
The first query will not return NULL employee_id and will return N^2 results for multiple entries with N occurrences.

Even simpler would be this:
select e.employee_ID, d.dep_name from employee e,Departement d where d.dep_id= e.departement_id

Related

SQL doesn't display rows where

The following sql query selects the employee name (from employee table), their manager's name (from manager table) and their performance (from rating table). However, if an employee's manager_id is missing, then it doesn't list that employee at all when outputting rows. Is there any way around this? Probably involving joins but not too sure. Thanks in advance :)
SELECT employee.name,
manager.name,
rating.performance
FROM employee,
manager,
rating
WHERE employee.manager_id = manager.id
AND rating.employee_id = employee.id;
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. In this case, you want a LEFT JOIN:
SELECT e.name, m.name, r.performance
FROM employee e LEFT JOIN
manager m
ON e.manager_id = m.id LEFT JOIN
rating r
ON r.employee_id = e.id;
Notice that this also includes table aliases to the query is easier to write and to read.
By using a LEFT JOIN you get all rows of the "left" table despite not being able to "pair" with any rows in the joining tables.
SELECT
employee.name,
manager.name,
rating.performance
FROM
employee LEFT JOIN,
manager ON employee.manager_id = manager.id LEFT JOIN
rating ON empoyee.id = rating.employee_id

Join a table in SQL based off two columns?

I have two tables:
Employees (columns: ID, Name)
and
employee partners (EmployeeID1, EmployeeID2, Time)
I want to output EmployeName1, EmployeeName2, Time instead of imployee ids.
(In other words, replace the ids with names, but in two columns at a time)
How would I do this? Would JOIN be the appropriate command?
you need to join the employee table 2 times as the employee partners table acts as many to many connection.
The select should be:
SELECT emp1.name, emp2.name, em.time
FROM Employees emp1
JOIN employee_partners em ON emp1.id = EmployeeID1
JOIN Employees emp2 on emp2.id = EmployeeID2
Often in these situations, you want to use LEFT JOIN:
SELECT e1.name as name1, e2.name as name2, em.time
FROM employee_partners ep LEFT JOIN
Employees e1
ON e1.id = ep.EmployeeID1 LEFT JOIN
Employees e2
ON e2.id = ep.EmployeeID2;
Notes:
The LEFT JOINs ensure that you do not lose rows if either of the employee columns is NULL.
Use tables aliases; they make the query easier to write and to read.
Qualify all columns names; that is, include the table name so you know where the column is coming from.
I also added column aliases so you can distinguish between the names.

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

sql query null data was not retrieved

Table DEPARTMEnT
TABLE EMPLOYEE
There is the Operations Department which has not any employee. So, i believed that the query would retrieved also the row(image 1):
Department_ID=10 , Department_Name =Operations, Employee=0
Why doesnt happen???
SELECT EMPLOYEE.Department_ID, DEPARTMENT.Department_Name, Count(*) AS Employees
FROM EMPLOYEE right JOIN DEPARTMENT ON DEPARTMENT.Department_ID = EMPLOYEE.Department_ID
GROUP BY DEPARTMENT.Department_Name,.EMPLOYEE.Department_ID
Since the principal data you care about for this query is coming from the DEPARTMENT table, you may want to consider rewriting your query to be:
SELECT DEPARTMENT.Department_ID, DEPARTMENT.Department_Name, Count(EMPLOYEE.Employee_ID) As Employees
FROM DEPARTMENT
LEFT JOIN EMPLOYEE ON EMPLOYEE.Department_ID = DEPARTMENT.Department_ID
GROUP BY DEPARTMENT.Department_ID, DEPARTMENT.Department_Name
The default join is an inner join, which only returns rows for which at least one row is found on both sides. Replace join with left join to retrieve departments without employees.
Example code:
SELECT e.Department_ID
, d.Department_Name
, count(e.Employee_ID) AS Employees
FROM Department d
LEFT JOIN
Employee e
ON d.Department_ID = e.Department_ID
GROUP BY
d.Department_ID
, d.Department_Name
This should do the trick. You could put in a RIGHT JOIN if you have the EMPLOYEE table first, but the reason this is not good is because soon your queries will start being a mix of LEFT and RIGHT joins, which becomes very hard to read, even for seasoned SQL professionals. By sticking with LEFT JOIN you keep the query maintainable and understandable. (In very rare circumstances RIGHT JOIN may simplify a query that has a complex order of precedence but I have only done it something like twice to avoid having to add parentheses around groups of joins).
SELECT
D.Department_ID,
D.Department_Name,
Employees = Count(*)
FROM
dbo.DEPARTMENT D
LEFT JOIN dbo.EMPLOYEE E
ON D.Department_ID = E.Department_ID
GROUP BY
D.Department_ID,
D.Department_Name
Also, I recommend that you use aliases for your tables instead of full table names. The query becomes much easier to scan and understand when there is consistent use of aliases. Spelling out the entire table name all too often obscures other parts of the query.

Explanation of self-joins

I don't understand the need for self-joins. Can someone please explain them to me?
A simple example would be very helpful.
You can view self-join as two identical tables. But in normalization, you cannot create two copies of the table so you just simulate having two tables with self-join.
Suppose you have two tables:
Table emp1
Id Name Boss_id
1 ABC 3
2 DEF 1
3 XYZ 2
Table emp2
Id Name Boss_id
1 ABC 3
2 DEF 1
3 XYZ 2
Now, if you want to get the name of each employee with his or her boss' names:
select c1.Name , c2.Name As Boss
from emp1 c1
inner join emp2 c2 on c1.Boss_id = c2.Id
Which will output the following table:
Name Boss
ABC XYZ
DEF ABC
XYZ DEF
It's quite common when you have a table that references itself. Example: an employee table where every employee can have a manager, and you want to list all employees and the name of their manager.
SELECT e.name, m.name
FROM employees e LEFT OUTER JOIN employees m
ON e.manager = m.id
A self join is a join of a table with itself.
A common use case is when the table stores entities (records) which have a hierarchical relationship between them. For example a table containing person information (Name, DOB, Address...) and including a column where the ID of the Father (and/or of the mother) is included. Then with a small query like
SELECT Child.ID, Child.Name, Child.PhoneNumber, Father.Name, Father.PhoneNumber
FROM myTableOfPersons As Child
LEFT OUTER JOIN myTableOfPersons As Father ON Child.FatherId = Father.ID
WHERE Child.City = 'Chicago' -- Or some other condition or none
we can get info about both child and father (and mother, with a second self join etc. and even grand parents etc...) in the same query.
Let's say you have a table users, set up like so:
user ID
user name
user's manager's ID
In this situation, if you wanted to pull out both the user's information and the manager's information in one query, you might do this:
SELECT users.user_id, users.user_name, managers.user_id AS manager_id, managers.user_name AS manager_name INNER JOIN users AS manager ON users.manager_id=manager.user_id
Imagine a table called Employee as described below. All employees have a manager which is also an employee (maybe except for the CEO, whose manager_id would be null)
Table (Employee):
int id,
varchar name,
int manager_id
You could then use the following select to find all employees and their managers:
select e1.name, e2.name as ManagerName
from Employee e1, Employee e2 where
where e1.manager_id = e2.id
They are useful if your table is self-referential. For example, for a table of pages, each page may have a next and previous link. These would be the IDs of other pages in the same table. If at some point you want to get a triple of successive pages, you'd do two self-joins on the next and previous columns with the same table's id column.
Without the ability for a table to reference itself, we'd have to create as many tables for hierarchy levels as the number of layers in the hierarchy. But since that functionality is available, you join the table to itself and sql treats it as two separate tables, so everything is stored nicely in one place.
Apart from the answers mentioned above (which are very well explained), I would like to add one example so that the use of Self Join can be easily shown.
Suppose you have a table named CUSTOMERS which has the following attributes:
CustomerID, CustomerName, ContactName, City, Country.
Now you want to list all those who are from the "same city" .
You will have to think of a replica of this table so that we can join them on the basis of CITY. The query below will clearly show what it means:
SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2,
A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City
ORDER BY A.City;
There are many correct answers here, but there is a variation that is equally correct. You can place your join conditions in the join statement instead of the WHERE clause.
SELECT e1.emp_id AS 'Emp_ID'
, e1.emp_name AS 'Emp_Name'
, e2.emp_id AS 'Manager_ID'
, e2.emp_name AS 'Manager_Name'
FROM Employee e1 RIGHT JOIN Employee e2 ON e1.emp_id = e2.emp_id
Keep in mind sometimes you want e1.manager_id > e2.id
The advantage to knowing both scenarios is sometimes you have a ton of WHERE or JOIN conditions and you want to place your self join conditions in the other clause to keep your code readable.
No one addressed what happens when an Employee does not have a manager. Huh? They are not included in the result set. What if you want to include employees that do not have managers but you don't want incorrect combinations returned?
Try this puppy;
SELECT e1.emp_id AS 'Emp_ID'
, e1.emp_name AS 'Emp_Name'
, e2.emp_id AS 'Manager_ID'
, e2.emp_name AS 'Manager_Name'
FROM Employee e1 LEFT JOIN Employee e2
ON e1.emp_id = e2.emp_id
AND e1.emp_name = e2.emp_name
AND e1.every_other_matching_column = e2.every_other_matching_column
Self-join is useful when you have to evaluate the data of the table with itself. Which means it'll correlate the rows from the same table.
Syntax: SELECT * FROM TABLE t1, TABLE t2 WHERE t1.columnName = t2.columnName
For example, we want to find the names of the employees whose Initial Designation equals to current designation. We can solve this using self join in following way.
SELECT NAME FROM Employee e1, Employee e2 WHERE e1.intialDesignationId = e2.currentDesignationId
One use case is checking for duplicate records in a database.
SELECT A.Id FROM My_Bookings A, My_Bookings B
WHERE A.Name = B.Name
AND A.Date = B.Date
AND A.Id != B.Id
SELF JOIN:
Joining a table by itself is called as Self Join.
We can perform operations on a single table.
When we use self join we should create alias names on a table otherwise we cannot implement self join.
When we create alias name on a table internally system is preparing virtual table on each alias name of a table.
We can create any number of alias names on a table but each alias name should be different.
Basic Rules of self join:
CASE-I: Comparing a single column values by itself with in the table
CASE-II: Comparing two different columns values to each other with in the table.
Example:
SELECT * from TEST;
ENAME
RICHARD
JOHN
MATHEW
BENNY
LOC
HYDRABAD
MUMBAI
HYDRABAD
CHENNAI
SELECT T1. ENAME, T1. LOC FROM TEST.T1, TEST T2 WHERE T1.LOC=T2.LOC AND T2.ENAME='RICHARD';
It's the database equivalent of a linked list/tree, where a row contains a reference in some capacity to another row.
Here is the exaplanation of self join in layman terms. Self join is not a different type of join. If you have understood other types of joins (Inner, Outer, and Cross Joins), then self join should be straight forward. In INNER, OUTER and CROSS JOINS, you join 2 or more different tables. However, in self join you join the same table with itslef. Here, we don't have 2 different tables, but treat the same table as a different table using table aliases. If this is still not clear, I would recomend to watch the following youtube videos.
Self Join with an example