Is there a SQL statement that will allow me to see results that match from 2 different tables? - sql

I'm joining two tables (Employee and Matrix) and I'm wondering if there is a statement I can use to only show the names of employees that have a matrix attached to their names after joining the Employee and Matrix tables. I thought of possibly using 'Distinct', but I don't believe that would work as I'm trying to only see employees that have a matrix and this information would be coming from two different tables.
Any suggestion is appreciated. Thank you in advance.

I think exists does what you want:
select e.*
from employee e
where exists (select 1 from matrix m where m.employee_id = e.employee_id);

It would definitely work:
SELECT DISTINCT e.name
FROM employee e
INNER JOIN matrix m
ON e.id = m.employee_id

Related

SQL - Why Does This Happen?

These are the tables that I'm working with.
With that in mind, I want to showcase the Employees that are both a supervisor and a manager.
But when I used this
select e1.fname,e1.lname
from employee e1,employee e2,department
where e1.ssn=e2.super_ssn and e1.ssn = Mgr_ssn
This was the output
I know I can solve the problem with 'distinct', but I'm more interested to know why the output turned out like it did.
How about exists?
select e.*
from employee e
where exists (select 1 from employee e2 where e2.mgr_ssn = e.ssn) and
exists (select 1 from employee e2 where e2.super_ssn = e.ssn) ;
Your query returns duplicates for two reasons. First, presumably managers and supervisors have multiple employees below them. You end up with rows for each such employee. Second, you have a cartesian product with department, which further multiplies the rows. The department table is not used in the query.
Using select distinct is not a good solution in this case. The database just ends up having to do a lot more work than necessary -- first to create the duplicate rows and then to remove them.
add department matching clause in where like
select e1.fname,e1.lname
from employee e1,employee e2,department d
where e1.ssn=e2.super_ssn and e1.ssn = Mgr_ssn and
d.Dnumber=e1.Dno

Duplicate table in Oracle query

I have a query that looks like this:
SELECT *
FROM
employees e,
departments d1,
departments d2,
departments d3,
departments d4
WHERE e.dep1 = d1.dep(+)
AND e.dep2 = d2.dep(+)
AND e.dep3 = d3.dep(+)
AND e.dep4 = d4.dep(+);
Is there a better way to write this so that I don't need to use the same table in my query multiple times? I know Oracle's optimizer probably works around this rather nicely, but if there is a more efficient way to write a query like this, I'm all ears. Keep in mind that the above is merely an example, my actual query has a lot more going on in it. I'm using Oracle 11.2.0.3 on Windows 2003 x64.
Thanks,
Tom
This is perfectly valid.
The contrived example me and my colleague often use is city_of_birth and city_of_residence. Let's assume we want to query employees who now live in a different country to which they were born in (and that all countries have states).
You would query this as follows:
select e.*
from employees e,
cities city_of_birth,
cities city_of_residence,
states state_of_birth,
states state_of_residence
where e.city_of_birth_id = city_of_birth.id
and e.city_of_residence_id = city_of_residence.id
and city_of_birth.state_id = state_of_birth.id
and city_of_residence.state_id = state_of_residence.id
and state_of_birth.country_id != state_of_residence.country_id;
The thing to note is that tables need to be referenced in the from clause of a query as often as there are different meanings to them.
Another way to think about it: you need to reference the same table multiple times in the from clause if you're going to be selecting different rows from each "instance".
If you want the details to all the departments flat in one row you need several joins but I suggest to write it this way:
SELECT *
FROM employees e
LEFT JOIN departments d1 on ( d1.dep = e.dep1 )
LEFT JOIN departments d2 on ( d2.dep = e.dep1 )
LEFT JOIN departments d3 on ( d3.dep = e.dep1 )
LEFT JOIN departments d4 on ( d4.dep = e.dep1 )
this doesn't make much sense to me... you are comparing an employee to find their department (when they have many possible in non-normalized columns) - what about using an OR clause...
SELECT *
FROM
employees e,
departments d
WHERE ( e.dep1 = d.dep
OR e.dep2 = d.dep
OR e.dep3 = d.dep
OR e.dep4 = d.dep );
or better - rework your table so it is properly structured. :)

select Two Employee Names from a single table with two different employee Ids in a single stored procedure

I am trying to solve this below query from one day but i didn't get the out put..
Query is:
select distinct L.LeadBudget,L.CompanyName,L.LeadTitle,L.Status,
E.Name as OwnerName,E.Name as
CreatedUser
from Leads L,Employee E where L.LeadId='2'
and E.EmployeeId=L.LeadOwner and E.EmployeeId=L.CreatedUserId
In The above query i want to get
E.Name as OwnerName and E.Name as CreatedUser
from a single Employee tables)..where E.EmployeeId=L.LeadOwner and
E.EmployeeId=L.CreatedUserId
if i execute with out OwnerName or Created User i am getting the data..but i want to get both the names.
I would suggest to use a more modern JOIN style; instead of listing multiple talbes and doing everything in the WHERE.
Basically to achiev what you want to do you will need to perform a JOIN for both employees.
SELECT l.LeadBudget, l.CompanyName, l.LeadTitle, l.Status, leadEmp.Name As OwnerName, createdEmp.Name As CreatedUser
FROM Leads l
INNER JOIN Employee leadEmp ON(l.LeadOwner = leadEmp.EmployeeId)
INNER JOIN Employee createdEmp ON(l.CreatedUserId= createdEmp.EmployeeId)
WHERE l.LeadId='2'

Query database not using stored procedure

i have a db diagram as shown above.
What I need to do is:
Select a table which is as follows:
PatientId, Emergency.Name or Doctor Names, Patient.Address.
Explanation; I need A query which will return patient details and, if Patient has an emergency also add an emergency, if not select all doctor.Name into one row.
So, example:
So, the first row was built because EmergencyId in table patient was null, while the second row had an emergency Id.
I need the query to simulate this. Using SSRS
Thanks a lot!
Thanks guys, can you at least explain
me how to return this data in separate
rows, so I can union later on?
I believe this will return the data you want broken out into separate rows, returning Emergency if it exists and the Drs if it does not. Good luck!
SELECT Distinct Coalesce(E.Name, D.Name) as VariableColumn,
P.PatientId,
P.Address
FROM Patient P
LEFT JOIN Emergency E
ON P.EmergencyId=E.EmergencyId
LEFT JOIN PatientDoctor PD
ON P.PatientID=PD.PatientId
LEFT JOIN Doctor D
ON PD.DoctorId=D.DoctorId
I can't really debug or work with your tables to check this, but here is a rough stab at something that should get you going:
SELECT P.PatientId, E.Name as 'EmergencyName', D.Name as 'DoctorName', P.Address
FROM Patient P
LEFT JOIN Emergency E ON P.EmergencyId=E.EmergencyId
LEFT JOIN PatientDoctor PD ON P.PatientID=PD.PatientId
LEFT JOIN Doctor D ON PD.DoctorId=D.DoctorId
ORDER BY P.PatientId, E.Name, D.Name, P.Address
Also, I'm no SQL Wizard. This should get the ball rolling, though.
Can you test this query against your data?
Does it return the desired results?
EDIT:
I just saw your comment about needing this layout with multiple values in one cell aligned vertically. That would require sub queries, and would be too much for me to write out.

Why table exists two times under different aliases in FROM clause of SQL query?

I have this query:
SELECT to_number(gr.code) group_index,
gr.NAME group_name, f.*,
gr.description gr_desc
FROM obj$groups gr, obj$group_objects gro,
obj$group_objects gro2, tdf$flex_fields f,
inv$requests w, inv$Direction_Criterions c
WHERE gr.NO = gro.object_no
AND gro.group_no = obj$group_service.path_to_no(
'Some Condition String',
tdf$flex_field_service.get_local_list_group_no)
AND gro2.group_no = gr.NO
AND f.NO = gro2.object_no
AND w.no = 11593597
AND c.direction_no = w.direction_no
AND f.no = c.criterion_no
ORDER BY to_number(gr.code), f.name
Why are two same tables (group_objects) present here? I tried to reverse-engineer this, but couldn't myself, maybe anyone here already know of this trick?
This happens in Oracle database.
It's an operation called self-join. When you want to join records from the same table.
It usually happens when you have records related to records in the same table. Example:
create table tree
(
id number primary key,
parent_id number,
value varchar2(100)
);
So, if you want to retrieve nodes and their parents you would do:
select c.id, c.value, p.value as parent_value
from tree c inner join tree p on (c.parent_id = p.id)
Something similar is happening in the query you posted.
group_objects is being joined to groups in the clause gro2.group_no = gr.NO and to flex_fields in the clause f.NO = gro2.object_no. I suspect this covers the case where obe set of group object isn't exactly the same as the other set and this limits the rows in the two joins where one join removes a group_object that would then not be available to join to the other table.
It's hard to divine the original programmer's intent from this snippet, especially without a description of what the various tables hold.
However, it appears to me as if the final result of this query is supposed to report information from two different records from the group_objects table — one in which the group no matches "Some Condition String" and the other in which the group no matches a column value from the groups table. If I had to guess, it's retrieving an operation in which an item was transferred between two groups, or substituted to be used in place of an object from a second group, or something like that.
For illustration, the equivalent with the standard EMP table would be:
select e.ename, m.ename manager_name
from emp e, emp m
where m.empno = e.mgr;
Or in more modern syntax:
select e.ename, m.ename manager_name
from emp e
join emp m on m.empno = e.mgr;
i.e. show the names of employees with managers and the name of their managers.
The point is that the same table is used twice in the query in a different "role". It need not be a self-join, there could be another table (or more) in between like this:
select e.ename, pm.ename projmanager_name
from emp e
join project_assignments pa on p.empno = pa.empno
join projects p on p.proj_id = pa.proj_id
join emp pm on pm.empno = p.projmanager_empno;
i.e. show the names of employees assigned to projects and show the name of the project manager of that project.