SQL Select colmn from other table only if data exist - sql

I have two tables and I'm selecting data from the first table. If the condition is meet(Alias type = 2) and the data in second table for the id from the first table exist the I want to select the column from the second table. Here is data to explain more:
Table 1
id | Name | Location
---+--------------+---------
34 |John Smith |NewYork
36 |Mike Smith |London
45 |Bob Smith |Los Angeles
Table 2
id | Alias | Alias type
---+-------------------+-------
36 |Warren Johnson |1
36 |William Williams |2
Wanted results if alias type = 2
id |Name | Location
---+-------------------+---------
34 |John Smith |NewYork
36 |William Williams |London
45 |Bob Smith |Los Angeles
Can you help me write query to get the wanted results? Tell me if I need to explain more. I'm using a SQL Server database.

You can use a left outer join onto Table2, and then COALESCE the Alias and Name results like this:
SELECT Table1.ID, COALESCE(Table2.Alias, Table1.Name) AS Name,
Table1.Location
FROM Table1
LEFT OUTER JOIN Table2 ON Table1.ID = Table2.ID AND Table2.AliasType = 2
COALESCE works by finding the first non-null value in the supplied values.

Try something like this -- you just need to use CASE:
SELECT T1.Id,
CASE WHEN T2.Alias IS NOT NULL THEN T2.Alias ELSE T1.Name END as Name,
t1.Location
FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.Id = T2.Id AND T2.AliasType = 2
Here is the SQL Fiddle.
Good luck.

The COALESCE function will let you have a fall-back expression so that the name from table 2 is used if it exists, and the name from table 1 is used otherwise. The LEFT outer join only joins table 2 when the rows exist, and t2.name is null if no record was joined.
SELECT t1.id, COALESCE(t2.name, t1.name), t1.location FROM [Table 1] as t1 LEFT JOIN [Table 2] as t2 on t1.id=t2.id and t2.[alias type]=2

Related

How to join a table with itself based on a foreign key in same table?

Let's say I have a SQL table as follows:
Id | Name | Email | Id_manager
---+------+--------------+------------
1 | Jon | jon#foo.com | 2
2 | Mike | mike#foo.com | 2
2 | Bar | bar#foo.com | 1
So here Jon is the manager of Bar and mike is the manager of John and himself. So Id_manager is a foreign key that references the same table.
I need to return a new table containing the following columns
Name, Email, Manager_Name
But I have no clue how to get the name of the manager using a SQL operation. Should I use a join? If so how can I do it in this case?
That's a self-join indeed:
select t.name, t.email, m.name as manager_name
from mytable t
inner join mytable m on m.id = t.id_manager
If there are employees without a manager, you might want to use left join instead of inner join to avoid filtering them out.
I think the answer can also be put in this way:
select t1.name, t1.email, t2.name as manager_name from mytable t1, mytable t2
where t1.id_manager = t2.id
I think the Id column should be unique, so I change the Id of Bar from 2 to 3.
The following can tell you the result when the id_manager column in t1 is equal to the Id column in t2.
t1 t2
Id|Name|Email |Id_manager Id|Name|Email |Id_manager
1 |Jon |jon#foo.com |2 2 |Mike|mike#foo.com|2
2 |Mike|mike#foo.com|2 2 |Mike|mike#foo.com|2
3 |Bar|bar#foo.com |1 1 |Jon |jon#foo.com |2

SQL combining two tables without duplication

I want to combine two tables based on a column. Here's an example:
These are my two tables:
Table1 Table2
Person | salary Person | Age
Tim | 22.50 Larry | 32
Tony | 49.00 Tim | 22
John | 32.67 Tony | 44
Kim | 23.42 John | 31
And my resulting table should be:
Person | salary | Age
Larry | | 32
Tim | 22.50 | 22
Tony | 49.00 | 44
John | 32.67 | 31
Kim | 23.42 |
Everyone is added to the resulting table only once even if they don't have a value for both salary and age
Thanks in advance!
Since you have tagged this as MS-ACCESS I will provide SQL code for MS ACCESS
Because Microsoft does not have the capability to do a FULL OUTER JOIN, you have to think of a clever way to use existing SQL commands to create a FULL OUTER JOIN. The following code should do the trick using your tables above:
SELECT Table1.Person, Salary, Age
FROM Table1 INNER JOIN Table2 ON Table1.Person = Table2.Person
UNION ALL
SELECT Table1.Person, Salary, Age
FROM Table1 LEFT JOIN Table2 ON Table1.Person = Table2.Person
WHERE Table2.Person Is Null
UNION ALL
SELECT Table2.Person, Salary, Age
FROM Table1 RIGHT JOIN Table2 ON Table1.Person = Table2.Person
WHERE Table1.Person Is Null
This could have been done by full outer join but since you are using ms access you will have to use union all in the below manner.
Try this out and let me know in case you face any difficulties.
SELECT * FROM table1 t1
LEFT JOIN
table2 t2
ON t1.person = t2.person
UNION all
SELECT * FROM table1 t1
RIGHT JOIN
table2 t2
ON t1.person = t2.person
I don't see what's your problem exactly but here is a SQL query that will do just what you have requested:
SELECT Person, salary, Age
FROM Table1 FULL OUTER JOIN Table2
WHERE Table1.Person = Table2.Person
Edit: This won't work on MS-ACCESS for its lack of support for FULL OUTER JOINS, the other two answers have explained the alternative.

How do you exclude another table from a query in SQL Server?

Let's assume you have the following two SQL Server tables:
t1:
|----------------------------------------------|
|name | day_planed | day_canceled | discription|
|----------------------------------------------|
|alpha| 2015-11-02 | 2015-11-01 | some |
|alpha| 2015-11-02 | 2015-10-30 | text |
|beta | 2015-11-02 | 2015-11-01 | here |
|----------------------------------------------|
t2:
|----------------------------------------------|
|name | day_planed | day_canceled | discription|
|----------------------------------------------|
|alpha| 2015-11-02 | 2015-10-30 | text |
|----------------------------------------------|
In an query of t1 I now want every entry except those of t2. I already tried something similar to
SELECT *
FROM t1 AS A
LEFT JOIN t2 as B ON (A.name = B.name
AND A.day_planed = B.day_planed
AND A.day_canceled != B.day_canceled)
Unfortunately I don't get it why it does not exclude the row from t2 in the query of t1.
A second question would be, if there is actual an easy way to make a query of t1 without t2 by just returning the row with the maximum description. I tried looking into it in SQL Server, but could only find the first identifier, which does not work for this "wonderful" implementation of sql...
There are a few ways to do it in this "wonderful" implementation.
SELECT * FROM t1
EXCEPT
SELECT * FROM t2
is one. Another is:
SELECT *
FROM t1
WHERE NOT EXISTS
( SELECT *
FROM t2
WHERE t2.name = t1.name
AND t2.day_planed = t1.day_planed
AND t2.day_canceled = t1.day_canceled
)
Or you could use LEFT JOIN and check for rows that didn't match with WHERE t2.name IS NULL after your ON clause. Like what you have but with = instead of !=
SELECT t1.*
FROM t1
LEFT JOIN t2
ON t2.name = t1.name
AND t2.day_planed = t1.day_planed
AND t2.day_canceled = t1.day_canceled
WHERE t2.name IS NULL;
If you want to check every column (including discription), go with EXCEPT.
You are just missing a where clause and a condition on discription. You also need to change != to =.
SELECT *
FROM t1 AS A
LEFT JOIN t2 as B ON (A.name = B.name
AND A.day_planed = B.day_planed
AND A.day_canceled = B.day_canceled
AND A.discription = B.discription)
WHERE B.Name IS NULL

Where clause to check against two columns in another table

I am struggling to get this answer for some reason.
I have two tables, table1 and table2 which look like this:
Table1:
ID Location Warehouse
1 London Narnia
2 Cyprus Metro
3 Norway Neck
4 Paris Triumph
Table2:
ID Area Code
1 London Narnia
2 Cyprus Metro
3 Norway Triumph
4 Paris Neck
I need to first select everything from table1 where table1.Location is in table2.Area AND table1.Warehouse is in table2.Code GIVEN THAT table1.Location is in table2.Area. I.e. I want:
ID Location Warehouse
1 London Narnia
2 Cyprus Metro
I have got to:
select
1.location
, 1.warehouse
from table1 1
where 1.location in (select area from table2)
and 1.warehouse in (select code from table2)
But this won't work because I need the second where clause to be executed based on the first where clause holding true.
I have also tried similar queries with joins to no avail.
Is there a simple way to do this?
Use exists:
select t.location, t.warehouse
from table1 t
where exists (select 1
from table2 t2
where t.location = t2.area and t.warehouse = t2.code
);
I should point out that some databases support row constructors with in. That allows you to do:
select t.location, t.warehouse
from table1 t
where(t1.location, t1.warehouse) in (select t2.area, t2.code from table2 t2);
Maybe I'm missing something, but a simple join on the two conditions would give you the result in your example:
select t1.*
from table1 t1
join table2 t2 on t1.Location = t2.Area
and t1.Warehouse = t2.Code;
Result:
| ID | Location | Warehouse |
|----|----------|-----------|
| 1 | London | Narnia |
| 2 | Cyprus | Metro |
Sample SQL Fiddle
You need to use JOIN.
I'll design the query in a while :)
EDIT:
SELECT
1.location
, 1.warehouse
FROM table1 1
JOIN table2 2 ON 1.location = 2.area AND 1.warehouse = 2.code

TSQL Match Employee Assignments to Time Punch

I have the following table that designates employee assignments.
Null indicates current assignment:
|EmployeeNum|EmployeeAssignment|BeginDate |EndDate |
|1003 |Analyst |01/01/1990|02/04/2013|
|1002 |Coordinator |05/14/2000|06/01/2013|
|1003 |Trainer |07/28/2010|NULL |
|1004 |Janitor |08/09/2013|NULL |
|1005 |IT |09/02/2013|12/21/2013|
Another table designates time punches and paid hours:
|EmployeeNum| DatePaid |hworked|
|1003 | 05/11/2013|7.5 |
|1004 | 09/01/2013|8.25 |
|1005 | 09/15/2013|5.45 |
Is there a method where I can use SQL to compare both tables to determine which assignment each employee had when they worked?
Simple INNER JOIN
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.employeenum = t2.employeenum
Just SELECT whatever you want in your query
I would be inclined to use a correlated subquery for this:
select t2.*,
(select EmployeeAssignment
from table1 t1
where t1.employeenum = t2.employeenum and
t2.datepaid between t1.begin_date and coalesce(t1.end_date, getdate())
) as EmployeeAssignment
from table2 t2;
EDIT:
You can also use outer apply to do pretty much the same thing.
Actually, given your data structure, an outer join should work as well:
select t1.*, t2.EmployeeAssignment
from table1 t1 left join
table2 t2
on t1.employeenum = t2.employeenum and
t2.datepaid between t1.begin_date and coalesce(t1.end_date, getdate())