Join using 2 'alternative' columns from one table - sql

I have 2 large tables like bellow in Teradata. I need to join them so that:
all records from Table A are kept - like A left join B
join is on A.client_id=B.client_id_1
but if B.client_id_1 is null, it can join on A.client_id=B.client_id_2
Table A
client_id
details_a
1
abc
2
def
3
ghi
4
jkl
Table B
client_id_1
client_id_2
details_b
1
null
123
null
2
456
3
3
789
The result should be like:
client_id
details_a
client_id_1
client_id_2
details_b
1
abc
1
null
123
2
def
null
2
456
3
ghi
3
3
789
4
jkl
null
null
null
The tables are large and the join is part of a larger script (other joins using Table B)
I tried something like
Table A LEFT JOIN Table B
ON (A.client_id = B.client_id_1 OR A.client_id = B.client_id_2)
But the result was product join that never finished.
I also want to avoid two left joins (on B.client_id_1 and on B.client_id_2) as it would result in having all columns from Table B twice. And the Table B is further used in following joins. Plus client_id=3 would have two records.
Any idea? And what is wrong with the JOIN using OR above?
Thanks, R.

You can use case statement:
Table A LEFT JOIN Table B
ON (A.client_id = case when B.client_id_1 is null then B.client_id_2 else B.client_id_1 end)
oR Coalesce:
Table A LEFT JOIN Table B
ON (A.client_id = Coalesce(B.client_id_1 ,B.client_id_2 ))
If B.client_id_1 is not null then Coalesce(B.client_id_1 ,B.client_id_2 ) will return B.client_id_1 but if it's null then the condition will return B.client_id_2 .

Related

Update multiple records in table by using a reference table SQL Server

I am trying to update a table in SQL by using references from two other tables. I need Table C to be updated with the ID of records from Table A but only where a column from Temp Table B exists in Table A
Table A
ID
ReferenceNumber
1
123
2
321
3
213
4
413
Temp Table B
ID
ExtractedNum
1
213
2
413
3
321
4
123
Expected Results
Table C
TableA_ID
TableB_ID
3
1
4
2
2
3
1
4
I've tried a few different queries but none of them work the way I need it to:
UPDATE table_c
SET
table_c.tablea_id = a.id -- int
FROM table_a a
WHERE table_c.tableb_id =
(
SELECT t.Id,
t.ExtractedNum
FROM #tempTableB t,
table_a a2
WHERE t.ExtractedNum = a2.ReferenceNumber
);
UPDATE c
SET c.tablea_id=a.id
FROM tableC c INNER JOIN
tableA a ON a.id=c.tablea_id INNER JOIN
#tempTableB b ON b.ExtractedNum=a.ReferenceNumber

Compare the same column values in a table and then the take their relationship value from other table

I have a table like below:
ID Role CompanyID
1 T 123
2 S 1234
3 B 12345
T's company id has relationship with S's and B's company ids.The value of their relationship is in another table like below:
Rel CompanyId1 CompanyId
Private 1234 123
Public 12345 123
Of course first I have to join the two tables and then I have to get the relationship of T(123) with S(1234) and B(12345) from the table 2 and on the basis of that I have to create another column which will be if the relationship of T with S and B is private then 1 and if public then 0
It should be like this
Id Role Companyid BoolCol
1 T 123 for T there is no need to fill this col can be null
2 S 1234 1 becoz rel b/w T and S is private
3 B 12345 0 becoz rel b/w T and B is public
The relationship is only of T with another companies not the other way around
Any help will be appreciated.......
Thanks
You can join the table using Left join on CompanyId in first table and CompanyId1 in second table and use case when statement to get the BoolCol column.
select a.*,case when b.rel = 'Private' then 1
when b.rel = 'Public' then 0
else NULL
end as BoolCol
from table1 a
left join
table2 b
on a.companyid = b.companyid1;
Let me know in case you of any queries.
you can try this code:
select id, role,a.companyid,rel,case when rel='Private' then 1 when rel='Public' then 0 else null end as boolcol
from first_table a left join relation_table b
on a.companid=b.companyid1

Left join with additional join condition on Raima

I am struggeling with a left join on a Raima database. I'd like to add an additional join condition, but in this case the join behaves like an inner join, thus I am losing some of the expected results.
Example:
TABLE_A
ID
-------
1
2
3
4
.
TABLE_B
A_ID | B
--------
1 | 1
2 | 1
2 | 2
3 | 2
Query
select * from TABLE_A left join TABLE_B
on TABLE_A.ID = TABLE_B.A_ID
and TABLE_B.B = 1
I am expecting the following result:
1 1 1
2 2 1
3 null null
4 null null
E.g. on an Oracle 11g I get the expected result, but on the Raima it shows me only the first two results. What is the problem here and how to fix it?
You need this
select * from A left join
(select * from B where B=1) bd
on A.ID = bd.A_ID
The query you gave will not give you expected result in oracle also. This will.
PS: Please use different names for table and column

Using multiple joins (e.g left join)

I would like to know what's the logic for multiple joins (for example below)
SELECT * FROM B returns 100 rows
SELECT B.* FROM B LEFT JOIN C ON B.ID = C.ID returns 120 rows
As I know using left join will returns any matching data from the left table which is B if data are found for both table. But how come when using left join, it returns more data than table B itself?
What am I do wrong or misunderstood here? Any guidance are very appreciated. Thanks in advance.
Let be table B:
id
----
1
2
3
Let be table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Any id from b is matched with ids from c, then id=2 will be matched twice. So a left join on id will return 4 rows even if base table B has 3 rows.
Now look at a more evil example:
Table B
id
----
1
2
2
3
4
table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Every id from b is matched with ids from c, then first id=2 will be matched twice and second id=2 will be matched twice so the result of
select b.id, c.name
from b left join c on (b.id = c.id)
will be
id name
------------
1 John
2 Mary
2 Mary
2 Anne
2 Anne
3 Stef
4 (null)
The id=4 is not matched but appears in the result because is a left join.
Look at the following example :
B = {1,2}
C = {(1,a),(1,b),(1,c),(1,d),(1,e)}
The result of B left join C will be :
1 | a
1 | b
1 | c
1 | d
1 | e
2 | null
The number of rows in the result is definitely larger than rows in B (2).
In general the number of rows in result of B left join C is bounded by B.size + C.size and not only by B.size as you think...
As per your query it do the join to B Table with C and B table is Left Table so it will display all the records of Left table in our case it is B and related from other Table in our Case it is C.

SQL Select Statement issue - returning rows conditionally on a 2nd table

I could really use some help with the following SQL Select statement scenario:
I need to select all rows from a table conditionally depending on whether a userID has already entered data into a second table with the same ID.
Example:
Select all rows from TABLE A for idNumber where idNumber not in
TABLE B
but for each idNumber that IS in TABLE B, still return row unless a
specific userID is in that row in TABLE B.
TABLE A
========
idNumber|type|Date
1 A 01/01/01
2 A 01/01/01
3 B 01/01/01
4 B 01/01/01
5 B 01/01/01
TABLE B
========
idNumber|type|userID
1 A 0000
3 B 0000
4 B 1111
userID to exclude records for = 1111
SQL Query should return:
idNumber|type|Date
1 A 01/01/01
2 A 01/01/01
3 B 01/01/01
5 B 01/01/01
Apologies for the long winded post but i hope it makes sense.
Many thanks in advance,
ukjezza.!!
Select idNumber, type, Date
From TableA
Where Not Exists (
Select 1
From TableB
Where TableB.idNumber = TableA.idNumber
And TableB.userID = 1111
)
Another choice:
Select TableA.idNumber, TableA.type, TableA.Date
From TableA
Left Join TableB
On TableB.idNumber = TableA.idNumber
And TableB.userId = 1111
Where TableB.idNumber Is Null
Looks like a LEFT JOIN and COALESCE could take care of it:
SELECT a.*
FROM TableA as a
LEFT JOIN TableB as b
ON a.idNumber = b.idNumber
WHERE COALESCE(b.userID, -1) != 1111
select A.*
from TableA as A
left outer join TableB as B
on A.idNumber = B.idNumber
where B.idNumber is null or
B.userID <> '1111'