Subquery in FROM clause - sql

Looking around in the (now-discontinued) documentation and found this example:
Subquery in FROM clause
A subquery in a FROM clause acts similarly to a temporary table that is generated during the execution of a query and lost afterwards.
SELECT Managers.Id, Employees.Salary
FROM (
SELECT Id
FROM Employees
WHERE ManagerId IS NULL
) AS Managers
JOIN Employees ON Managers.Id = Employees.Id
(Excerpted from Subqueries - Subquery in FROM clause. The original author was Phrancis. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive. Reference topic ID: 1030 and example ID: 3327.)
My question is:
why using an extra ManagerId. An Id column is already in
Employees table,
why have the extra ManagerId to be null for a manager (ok it wants to be a joke).
My opinion:
despite the upvotes, something is wrong with this is example,
Tables with example data would be nice to see on the fly how it's working. One table with start data, one table temporary SELECT and one table the
resultset.
Edit: Thanks to all contributors for their answers!
#Alex K.: That is my point of view "it is not something one would actually use". But people, who wants to learn SQL, might think, that it is good practice, because it is in the documentation here.,
#Nebi: Thanks for the point that one would write it simpler to get the same result.
#Unnikrishnan R: "showcase how the sub query works" does in my eyes not only mean that it is fully functional but additional that it makes sense. If I get things simpler, why doing it the errorprone hard way.
#me: should have titled it "let's discuss sql documentation" or like that ;)

Let us consider a situation where Employee table holds all employees including their managers in which employee has an Id, and there is also a column for the manager Id (which can be null). This can be the point of view ,who was writing that SQL queries.
For Example,
+----+-------+--------+-----------+
| Id | Name | Salary | ManagerId |
+----+-------+--------+-----------+
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | NULL |
| 4 | Max | 90000 | NULL |
+----+-------+--------+-----------+
why have the extra ManagerId to be null for a manager --
getting the employees that are not managers

It is just an example how to do/ use Subqueries.
To your questions:
why using an extra ManagerId. An Id column is already in Employees
table
First of all ManagerId and Id are different columns of the table Employees. So there is a difference between them. But you might reffering to the Id of the Subquery Managers and the Id of the joined table Employees.
Then you need to define which Id you are using. Else you get the Error for ambigiuos column. In this example you to specify either the Subqueries Id which is Managers.Id or the Id of the joined table Employees (Employees.Id). Which one you choose is totally regardless because you use INNER JOIN one the Id.
why have the extra ManagerId to be null for a manager (ok it wants
to be a joke).
This is because of getting all the Employees that have are not managers. You are right about saying this could be done easier or in other form. For instance:
SELECT Id, Salary
FROM Employees
WHERE ManagerId IS NULL
This probably gets the same result as in the original. But the example is not about that, it is about the structure of a subquery.

why using an extra ManagerId. An Id column is already in Employees table
Consider you are having an employee table and you also wanted to keep the manager information in the same table.so apart from the ID column you need to add another column to keep the managerid.
why have the extra ManagerId to be null for a manager (ok it wants to be a joke).
The query is just to showcase how the sub query works. In this case subquery retrieves the manager from the Employee table (managerID is null) then join those id's with Employee table in the outer query to get the salary of each managers.

Related

select users with same social security number different badge numbers

Hello as the title suggest I need help writing a query that does this. I need to find all the users who have had a badge number change. So in the database there are often two records for the same person but both have a different badge number. Im assuming it's the same person if the social matches.
Table:
Badge_no | SSN
123123 | 387-47-1234 2
34837 | 387-47-1234
837532 | 543-45-6392
584391 | 543-45-6392
In this case I would want it to output:
837532 | 543-45-6392
584391 | 543-45-6392
Thank you!
I believe the following should do the trick here:
SELECT *
FROM yourtable
WHERE SSN IN (SELECT SSN FROM yourtable GROUP BY SSN HAVING Count(*) >=2);
That subquery will return SSN's that have more than one record. We use those SSN's to select, again, from the table to get all of the fields associated to them.

Excessive Case Statement Help - SQL Server

I'm supposed to answer this for class, and it's tricky (for me)
Write a SELECT query to output the name of all employees with the name of their supervisor. If the employee has no supervisor, the supervisor name column should contain the text 'No Supervisor'.
The primary key field in my db is the employeeid and they are provided with names, and each student also has a supervisorid
The table for this is shown below (sorry for the layout):
employeeid lastname firstname salary supervisorid
1 Stolz Ted 25000 NULL
2 Boswell Nancy 23000 1
3 Hargett Vincent 22000 1
4 Weekley Kevin 22000 3
5 Metts Geraldine 22000 2
6 McBride Jeffrey 21000 2
7 Xiong Jay 20000 3
I was wondering how I could go about this statement without using the case statement to apply each of the 7 students with:
when concat(firstname,' ',lastname)='Nancy Boswell' then 'Ted Stolz'
In larger tables this would simply be a HUGE statement, is there a better way to do it?
Thanks!
EDIT:
I've now tried this:
SELECT
EMP1.employeeid as 'employee',
EMP2.supervisorid as 'manager'
FROM
employee EMP1
LEFT OUTER JOIN
employee EMP2
ON
emp1.employeeid = emp2.supervisorid;
However, I am seeing duplicate fields, for some reason employee 2 and 3 are appearing twice, meaning there are 9 fields showing instead of 7.
Also, I need to display their names, not their id's does that mean I need to join the join that i've already done to the employee name ? How would I do this?
Thanks for the feedback guys!
You need to link the table with itself based on the supervisorId. This might be strange if you are new to SQL but it is very common to do. You tell with SQL to add the row of the supervisor to the row of the employee via its primary key.
SELECT
*
FROM
EMPLOYEES EMP1
LEFT OUTER JOIN
EMPLOYEES EMP2
ON
-- make link between tables here
Note that the above query is not 100% correct / complete, its an indication. The LEFT OUTER JOIN statement makes the employees without supervisor have null values for the supervisor, otherwise the whole record would be left out.

Display all managers and employees without a manager

I have a table in SQL Server 2008 that for explanation purposes contains, ID, Employee and ManagerID.
eg:
ID Employee ManagerID
1 A NULL
2 B 2
3 C 2
I want to write a query that returns all non related ManagerID's and ID's where ManagerID is equal to the ID.
The result should look like this,
ID Employee ManagerID
1 A NULL
2 B 2
In essence no managers can be managers of managers.
At first I thought that it would be simple using a SELF Join and an EXCLUDE SQL statement however I cannot get this to work. I would prefer not to USE the EXCLUDE statement as my actual table has more columns and related data that I would like to return.
If you could help, I would be grateful.
select employee, managerid
from your_table
where managerid is null
or managerid = id

How do I make a query for if value exists in row add a value to another field?

I have a database on access and I want to add a value to a column at the end of each row based on which hospital they are in. This is a separate value. For example - the hospital called "St. James Hospital" has the id of "3" in a separate field. How do I do this using a query rather than manually going through a whole database?
example here
Not the best solution, but you can do something like this:
create table new_table as
select id, case when hospital="St. James Hospital" then 3 else null
from old_table
Or, the better option would be to create a table with the columns hospital_name and hospital_id. You can then create a foreign key relationship that will create the mapping for you, and enforce data integrity. A join across the two tables will produce what you want.
Read about this here:
http://net.tutsplus.com/tutorials/databases/sql-for-beginners-part-3-database-relationships/
The answer to your question is a JOIN+UPDATE. I am fairly sure if you looked up you would find the below link.
Access DB update one table with value from another
You could do this:
update yourTable
set yourFinalColumnWhateverItsNameIs = {your desired value}
where someColumn = 3
Every row in the table that has a 3 in the someColumn column will then have that final column set to your desired value.
If this isn't what you want, please make your question clearer. Are you trying to put the name of the hospital into this table? If so, that is not a good idea and there are better ways to accomplish that.
Furthermore, if every row with a certain value (3) gets this value, you could simply add it to the other (i.e. Hospitals) table. No need to repeat it everywhere in the table that points back to the Hospitals table.
P.S. Here's an example of what I meant:
Let's say you have two tables
HOSPITALS
id
name
city
state
BIRTHS
id
hospitalid
babysname
gender
mothersname
fathername
You could get a baby's city of birth without having to include the City column in the Births table, simply by joining the tables on hospitals.id = births.hospitalid.
After examining your ACCDB file, I suggest you consider setting up the tables differently.
Table Health_Professionals:
ID First Name Second Name Position hospital_id
1 John Doe PI 2
2 Joe Smith Co-PI 1
3 Sarah Johnson Nurse 3
Table Hospitals:
hospital_id Hospital
1 Beaumont
2 St James
3 Letterkenny Hosptial
A key point is to avoid storing both the hospital ID and name in the Health_Professionals table. Store only the ID. When you need to see the name, use the hospital ID to join with the Hospitals table and get the name from there.
A useful side effect of this design is that if anyone ever misspells a hospital name, eg "Hosptial", you need correct that error in only one place. Same holds true whenever a hospital is intentionally renamed.
Based on those tables, the query below returns this result set.
ID Second Name First Name Position hospital_id Hospital
1 Doe John PI 2 St James
3 Johnson Sarah Nurse 3 Letterkenny Hosptial
2 Smith Joe Co-PI 1 Beaumont
SELECT
hp.ID,
hp.[Second Name],
hp.[First Name],
hp.Position,
hp.hospital_id,
h.Hospital
FROM
Health_Professionals AS hp
INNER JOIN Hospitals AS h
ON hp.hospital_id = h.hospital_id
ORDER BY
hp.[Second Name],
hp.[First Name];

Counting Distinct Values in large dataset (40M rows): SELECT count(*) as count, name FROM names GROUP BY name ORDER BY name;

CREATE TABLE `names` ( `name` varchar(20) );
Assume the names table contains all 40 million first names of everyone living in California (for example).
SELECT count(*) as count, name FROM names GROUP BY name ORDER BY name;
How can I optimize this query?
Expected Result:
count | name
9999 | joe
9995 | mike
9990 | kate
.... | ....
2 | kal-el
You have to create an index on the name column of your table. The query is as good as it can be.
Well, what makes you think it's not already optimised? This looks like the sort of query a good database engine should be able to handle relatively easily - particularly if you've got an appropriate index on your table.
Do you actually have a bottleneck here, or are you worrying about something that might happen in the future? If it's the latter, I suggest you try it with your RDBMS (by generating dummy data), and see what happens.