Return all records regardless if there is a match - tsql

In my Table 1, It may have AND have a null entry in the address column to corresponding record OR not have a matching entry in Table 2.
I want to present all the records in Table 1 but also present corresponding entries from Table 2. My RESULT is what I am trying to achieve.
Table 1
ID First Last
1 John Smith
2 Bob Long
3 Bill Davis
4 Sam Bird
5 Tom Fenton
6 Mary Willis
Table 2
RefID ID Address
1 1 123 Main
2 2 555 Center
3 3 626 Smith
4 4 412 Walnut
5 1
6 2 555 Center
7 3
8 4 412 Walnut
Result
Id First Last Address
1 John Smith 123 Main
2 Bob Long 555 Center
3 Bill Davis 626 Smith
4 Sam Bird 412 Walnut
5 Tom Fenton
6 Mary Willis

You need an outer join for this:
SELECT * FROM Table1 t1 LEFT OUTER JOIN Table2 t2 ON t1.ID = t2.RefID

How do you join those two tables? If table 2 have more than 1 matched address, how do you want display them? Please clarify in your question.
Here is a query based on my assumptions.
SELECT
ID, First, Last,
Address = (SELECT MAX(Address) FROM Table2 t2 WHERE t1.ID = t2.ID)
FROM Table1 t1

Related

Replace empty strings with NULL instead of empty strings when using JOIN

I have two tables:
table_a
id name
1 john
2 dave
3 tim
4 marta
5 jim
table_b
id sum random_metric
1 10.50 abc
3 11.5 efg
5 5.76 ghj
I have joined them on id
SELECT ...
FROM table_a
LEFT JOIN table_b ON table_a.id = table_b.id
and I get:
id name sum random_metric
1 john 10.5 abc
2 dave
3 tim 11.5 efg
4 marta
5 jim 5.76 ghj
Then I want to convert the sum column to double precision but since it has empty strings in rows 2, 4 it does not work.
How could I join tables so that I would have this:
id name sum random_metric
1 john 10.5 abc
2 dave NULL NULL
3 tim 11.5 efg
4 marta NULL NULL
5 jim 5.76 ghj

Full Outer Joins In PostgreSql [duplicate]

This question already has answers here:
Left Outer Join Not Working?
(4 answers)
Closed 4 years ago.
I've created a table of students with columns student_id as primary key,
student_name and gender.
I've an another table gender which consists of gender_id and gender.
gender_id in student refers to table gender.
Tables data looks like this:
Student table
STUDENT_ID STUDENT_NAME GENDER
1 Ajith 1
2 Alan 1
3 Ann 2
4 Alexa 2
5 Amith 1
6 Nisha 2
7 Rathan 1
8 Rebecca 2
9 asdf null
10 asd null
11 dbss null
Gender Table
GENDER_ID GENDER
1 Male
2 Female
3 Others
My query and its result
SELECT S.STUDENT_NAME,
G.GENDER
FROM STUDENTS S
FULL OUTER JOIN GENDER G ON G.GENDER_ID = S.GENDER
result is giving with 12 rows including the Others value from the gender table.
STUDENT_ID STUDENT_NAME GENDER
1 Ajith Male
2 Alan Male
3 Ann Female
4 Alexa Female
5 Amith Male
6 Nisha Female
7 Rathan Male
8 Rebecca Female
Others
9 asdf
10 asd
11 dbss
I'm trying to restrict a particular student_id:
SELECT S.STUDENT_ID,
S.STUDENT_NAME,
G.GENDER
FROM STUDENTS S
FULL OUTER JOIN GENDER G ON G.GENDER_ID = S.GENDER
WHERE S.STUDENT_ID <> 11;
now the the total number of the rows are reduced to 10.
STUDENT_ID STUDENT_NAME GENDER
1 Ajith Male
2 Alan Male
3 Ann Female
4 Alexa Female
5 Amith Male
6 Nisha Female
7 Rathan Male
8 Rebecca Female
9 asdf
10 asd
Why has the one row with Others Values disappeared from the second select query?
I'm trying to find the cause of this issue.
That's because NULL <> 11 is not TRUE, but NULL, and only rows where the condition is TRUE are included in the result.
You'd have to write something like
WHERE s.student_id IS DISTINCT FROM 11
Your second select query returns all rows where student_id is different (<>) from 11.

query multiple attribute in a table with single attribute in another table

I can't explain my problem in English well. So I write my problem in a personal way.
user_id name surname
1 john great
2 mary white
3 joseph alann
event_id official_id assistant_id date
1 1 2 2017-12-19
2 1 3 2017-12-20
3 2 3 2017-12-21
I want to get names at the same time when I query an event. I tried:
SELECT * FROM event a, user b WHERE a.official_id=b.user_id AND a.assistant_id=b.user_id
When I use "OR" instead of "AND" gives me cartesian result. I want the result like:
event_id off_id off_name asst_id asst_name date
1 1 john 2 mary 2017-12-19
2 1 john 3 joseph 2017-12-20
3 2 mary 3 joseph 2017-12-21

PostgreSQL Query to get the output from same table with same table values

I have one table
id employee leave_days leave_type type
1 ABC 10 sick remove
2 ABC 20 sick add
3 ABC 15 Annual remove
4 ABC 50 Annual add
5 XYZ 10 sick remove
6 XYZ 20 sick add
7 XYZ 15 Annual remove
8 XYZ 50 Annual add
From the above table I will group by the column name called leave_type and then I will merge rows and the output should be as follows.
I have to group by column name leave_type and add new column called leave_allocated . In the leave_allocated column, the column type with value add only will come.
id employee leave_days leave_type leave_allocated
1 ABC 10 sick 20
2 ABC 15 Annual 50
3 XYZ 10 sick 20
4 XYZ 15 Annual 50
I tried with sub query I could not match the inner query with outer query .
This should help
SELECT id,
employee,
leave_dates,
leave type,
(SELECT leave_days
FROM TABLE t2
WHERE t2.id = t1.id
AND t2.type = 'add'
) leave_allocated
FROM TABLE t1
WHERE t1.type = 'remove'

Query to match multiple column values with multiple rows

I have the following table in my postgresql 9.1
Table contact:
contact_id phone mobile
1 123 456
2 111 222
3 333 123
4 222 444
Table role:
contact_fk exchange
7 1
8 2
1 4
5 5
2 4
4 5
I need the result like:
contact_id phone mobile exchange
1 123 456 4
3 333 123 4
2 111 222 4
I want all the contact data whose mobile field data is in any other contacts phone field and the user must be in exchange 4, which is available in contact_role table
FYI: the contact table contains around 50k rows so joining the contact table to itself taking a lot time, so we must apply the contact_role condition together.
Joining 50k table with 2 columns (where contact_fk is probably primary) shouldn't take long time.
SELECT t1.contact_id, t1.phone, t1.mobile, t2.exchange
FROM contact as t1
JOIN role as t2 ON t1.contact_id = t2.contact_fk
WHERE t2.exchange = 4
Or if you have index on exchange column, this probably will be faster:
SELECT t1.exchange, t2.contact_id, t2.phone, t2.mobile
FROM role as t1
JOIN contact as t2 ON t1.contact_fk = t2.contact_id
WHERE t1.exchange = 4
Here is the answer
select t1.contact_id,
t1.phone,
t1.mobile,
t2.phone,
t2.exchange
from contact t1
inner join (select contact_id,
mobile,
phone,
exchange
from contact, contact_role
where contact.contact_id = contact_fk
and exchange = 4
) t2
on t1.mobile = t2.phone
and t1.mobile != '';