How to use Outer Join with date paramter situation - sql

I want to join these three tables with outer join
Table1
ID NAME
123 KING
456 KONG
Table2:
ID A_DATE VALUE
123 9/1/2015 1000
123 8/1/2015 1100
123 7/1/2015 1200
456 8/1/2015 900
456 7/1/2015 800
Table3:
Date
9/1/2015
Query Using:
select t1.ID, t1.NAME, t2.A_Date t2.Value
from Table1 t1, Table2 t2
where t1.ID = t2.ID(+)
and t2.A_Date = (Select Date from Table3)
Current Results:
ID NAME A_DATE VALUE
123 KING 9/1/2105 1000
This query only giving me common value.
Results Required:
ID NAME A_DATE VALUE
123 KING 9/1/2105 1000
456 KONG NULL NULL

You should write this using ANSI JOIN syntax, and put the constraint on the second table in the ON clause.
SELECT t1.ID, t1.NAME, t2.A_Date, t2.Value
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.ID = t2.ID AND t2.A_Date = (SELECT Date FROM Table3)
Using implicit joins, you need to test specifically for NULL.
select t1.ID, t1.NAME, t2.A_Date t2.Value
from Table1 t1, Table2 t2
where t1.ID = t2.ID(+)
and t2.A_Date IS NULL OR t2.A_Date = (Select Date from Table3)

Related

prefer table 3 over table 2 and table 2 over table 1

I have 3 tables with names and number of few of my friends.
Table 3 has correct data, table 2 has minute errors in data and table 1 has more than table 2.
if a user exists in table 2 and 3 then show table 3 details in output else table 2 details, if user is not even there in table 2 then show user data from table1.
more like a preference order.
DUMMY DATA:
table 1 :
name phone
abc 2343
bcd 3434
ccd 3455
ffc 4545
table 2 :
name phone
abc 2313
bcd 3414
ccd 3415
table 3 :
name phone
abc 2344
bcd 3431
expected output :
name phone
abc 2344
bcd 3431
ccd 3415
ffc 4545
I tried this query but unable to find correct output.
select phone,
coalesce(table1.name, TABLE2.name,TABLE3.name) as namee
FROM TABLE1
left JOIN TABLE2
ON table1.name = table2.name
INNER JOIN table3
ON table3.name = table2.name
Would be a huge, huge heeelppppp.
Gordon was close; he had the preference backwards. Please make sure you understand why the script works.
-- grab all our preferred data first
select t3.*
from table3 t3
union all
-- grab anything that doesn't exist in our preferred table
select t2.*
from table2 t2
where not exists (select 1 from table3 t3 where t3.name = t2.name)
union all
-- grab anything that doesn't exist in our preferred tables
select t1.*
from table1 t1
where not exists (select 1 from table2 t2 where t2.name = t1.name) and
not exists (select 1 from table3 t3 where t3.name = t1.name);
Use union all:
select t1.*
from table1 t1
union all
select t2.*
from table2 t2
where not exists (select 1 from table1 t1 where t1.name = t2.name)
union all
select t3.*
from table3 t3
where not exists (select 1 from table1 t1 where t1.name = t3.name) and
not exists (select 1 from table2 t2 where t2.name = t3.name);

Inner Join on 2 tables having multiple join value

I have the following tables where a few of the columns are included here:
Table 1:
Id RefId PhoneNumber
1 11 919191
2 11 888888
3 11 919191
Table 2:
Id RefId City UniqueId
1 11 Mumbai 111
2 11 Pune 222
3 11 Nashik 333
I want a few columns from Table1 and Table2. Common in both table is RefId. Table2 has UniqueId which is primary key of Table2. If I do an inner join based on RefId I will get 9 records, but I want 3. How do I get that?
Here is my query:
SELECT T1.PhoneNumber,T2.City,T2.UniqueId,T2.RefId
FROM Table1 T1
INNER JOIN Table2 T2
ON T1.RefId = T2.RefId
If the ID is used to join as well then
SELECT t1.Id, t1.RefId, t1.PhoneNumber, t2.City, t2.UniqueId
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.Id = t2.Id
AND t1.RefId = t2.RefId
If the Ids are randomly generated them you probably shouldn't join on them.
If the Ids were random but all of the PhoneNumbers were for the same place then you could just pick the Minimum value PhoneNumber (or Max)
SELECT t2.RefId, t1.PhoneNumber, t2.City, t2.UniqueId
FROM Table2 t2
INNER JOIN (
SELECT RefId, MIN(PhoneNumber) AS PhoneNumber
FROM Table1
GROUP BY RefId
) t1 ON t1.RefId = t2.RefId

Linking two tables to find a record only if there isn't a record in another table

I have two tables...
tbl1
ClientNo ApptID Status
1234 1 121
1234 2 121
1235 1 121
1235 2 121
tbl2
ClientNo Valid
1234 17
I'm looking to select all clients from tbl1 - where ApptID = 2, and there is no corresponding record in tbl2. So based on this data, 1234 has a record in tbl2, then no need to display it in end result.
I would love to see this as the end result:
ClientNo ApptID Status
1235 2 121
You can try the following query:
SELECT t1.*
FROM tbl1 AS t1
WHERE t1.ApptID = 2 AND
NOT EXISTS (SELECT 1
FROM tbl2 AS t2
WHERE t1.ClientNo = t2.ClientNo )
Please try the below answer:
SELECT * FROM TBL2 T2
RIGHT JOIN
(SELECT * FROM TBL1 WHERE ApptID = 2) TBL T1
ON T2.ClientNo = T1.ClientNo
WHERE T2.ClientNo IS NOT NULL;
You need to compare the join field to NULL
SELECT t1.* FROM tbl1 t1
LEFT JOIN tbl_2 t2
ON t1.ClientNo = t2.ClientNo
WHERE t1.ApptID=2 AND t2.ClientNo IS NULL
Or use sub-query as below:
SELECT * FROM tbl1
WHERE ApptID=2 AND ClientNo NOT IN (SELECT ClientNo FROM tbl_2)
This question was asked and answered a lot of times:
https://stackoverflow.com/a/5840232/1334425
https://stackoverflow.com/a/4076157/1334425
https://stackoverflow.com/a/6528786/1334425
https://stackoverflow.com/a/6613752/1334425
https://stackoverflow.com/a/6601945/1334425
You need to join with a first condition matching and a second condition which specifies the failed match:
SELECT t1.ClientNo
FROM tbl1 t1
LEFT JOIN tbl2 t2 ON
t1.ClientNo = t2.ClientNo
AND t1.ClientNo IS NULL

Distinct SQL Join two tables

I am trying to join two tables such that I am getting only a first match from the Right table instead of every match in Table2.
So if the query is:
SELECT T1.Name, T2.Dates
FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.ID = T2 = ID
WHERE T1.Name = 'John'
I would like to see
John | 14/11/14
Joe | 10/10/2014
Jane | 25/10/2014
Instead of
John | 14/11/2014
John | 12/10/2014
Joe | 10/10/2014
Jane | 25/10/2014
Jane | 26/10/2014
Which join should I use?
You need to decide which row, you should select. Min or max as commented.
SELECT T1.Name,
( SELECT MIN( T2.Dates) FROM Table2 T2 WHERE T1.ID = T2 = ID) AS Dates
FROM Table1 T1
WHERE T1.Name = 'John'
The ANSI standard function row_number() can be a big help here. It is supported by most databases, so you can do:
SELECT T1.Name, T2.Dates
FROM Table1 T1 LEFT JOIN
(SELECT t2.*, ROW_NUMBER() OVER (PARTITION BY t2.ID ORDER BY t2.DATE DESC) as seqnum
FROM Table2 t2
) T2
ON T1.ID = T2.ID AND seqnum = 1
WHERE T1.Name = 'John';
In your question, you have only one column from the second table, so you can also do this with aggregation:
SELECT t1.ID, t1.Name, MAX(t2.Date)
FROM Table1 T1 LEFT JOIN
Table2 T2
ON t1.ID = t2.ID
WHERE T1.Name = 'John'
GROUP BY t1.ID, t1.Name;
Query
SELECT a.name,
MAX(b.Dates)
FROM tbl1 a
JOIN tbl2 b
ON a.id=b.id
WHERE a.name='John'
GROUP BY a.name;
Demo

Join sql results

Please, help me with join results of commands (MS SQL):
SELECT name,value FROM table1 WHERE idfoo1 IN(SELECT _id FROM table3 where id = 1);
SELECT value FROM table2 WHERE idfoo2 IN(SELECT _id_2 FROM table3 where id = 1) AND name='fooname';
And I get:
name value
John 2
Bill 32
Alex 11
value
434
234
144
But I need join results.
name value value
John 2 434
Bill 32 234
Alex 11 144
So, id == id, _id != _id_2,
Use this query:
SELECT t1.name,
t1.value,
t2.value
FROM table1 t1
INNER JOIN table3 t3 ON t1.idfoo1 = t3._id
INNER JOIN table2 t2 ON t2.idfoo2 = t3._id_2
WHERE t3.id=1 AND t2.name = 'fooname'
Select a.name,a.value,c.value FROM table1 as a inner join table3 as b
on a.idfoo1=b.id and b.id=1 inner join table3 as c
on c.idfoo2=b._id_2 and b.id=1 and c.name='fooname'
i guess this is what you need-
SELECT t1.name, t1.value, t2.value
FROM table1 t1, table2 t2, table3 t3
WHERE
t1.idfoo1 = t3._id
AND t2.idfoo2 = t3._id_2
AND t3.id = 1
AND t2.name='fooname';