简体   繁体   中英

Only use data from TableA when TableB has no matching entry

So i have:

Table A with (not only Name - Multiple Columns):

| IDA        | Name        |
|:-----------|------------:|
| 1          |        John |
| 2          |       Jonas | 
| 3          |        Carl | 
| 4          |         Foo |
| 5          |         Bar |
| 6          |         Dog |

Table B with (not only Name - Multiple Columns):

| IDB        | Name        |
|:-----------|------------:|
| 1          |         Bob |
| 2          |        Lisa | 

Table MAIN with:

| ID         | FKtoB       | FKtoA       |
|:-----------|------------:|------------:|
| 1          |           1 |           4 |
| 2          |             |           3 | 
| 3          |             |           1 | 
| 4          |           2 |           6 |
| 5          |             |           2 |
| 6          |             |           5 |

My goal is to select from MAIN and prefer to use the data of Table B but if not Available i will use the data of Table A. I tryed to use coalesce but that didn't help because i dont want to mix the data, so if for example Table B has the data for one row, then in this row there should be no data from Table A.

My Query looks like that:

select 
coalesce(b.name, a.name) as surname, coalesce(b.surname, a.surname) as surname 
from MAIN m
left join TableA a on a.IDA = m.FKtoA
left join TableB b on b.IDA = m.FKtoB

My Problem there is that if for example b.name is filled and b.surname isn't it would mix b.name with a.surname, thats not okay in my case.

Try Left Join with Case -

SELECT
    M.ID, (CASE WHEN B.IDB IS NOT NULL THEN B.Name ELSE A.Name END) AS NAME
FROM
    MAIN AS M
    LEFT JOIN TableB as B ON B.IDB = M.FKtoB
    LEFT JOIN TableA as A ON A.IDA = M.FKtoA

Maybe you could add the non-existens of b as join criteria:

select 
coalesce(b.name, a.name) as name, coalesce(b.surname, a.surname) as surname 
from MAIN m
left join TableB b on b.IDA = m.FKtoB
left join TableA a on a.IDA = m.FKtoA and b.IDA is null

EDIT: corrected one surname to name

From SQL Server 2012 (and higher) you can use IIF :

SELECT
IIF(m.FKtoB IS NULL, A.name, B.name) AS surname
FROM MAIN m
LEFT JOIN TableA a ON a.IDA = m.FKtoA
LEFT JOIN TableB b ON b.IDA = m.FKtoB

try this:

    declare @tableA table(IDA INT,Name varchar(MAX))
    declare @tableB table(IDB INT, Name VARCHAR(MAX))
    declare @tableMain table(ID INT,FKtoB INT,FKtoA INT)

    INSERT INTO @tableA
    SELECT 1,'John'
    union all
    SELECT 2, 'Jonas'
    union all
    SELECT 3, 'Carl'
    union all
    SELECT 4,'Foo'
    union all
    SELECT 5 ,'Bar'
    union all
    SELECT 6,'Dog'


    INSERT INTO @tableB
    SELECT 1, 'Bob'
    Union all
    SELECT 2, 'Lisa'


    INSERT INTO @tableMain
    SELECT 1,1,4
    union all
    SELECT 2,null,3
    union all
    SELECT 3,null,1
    union all
    SELECT 4,2,6
    union all
    SELECT 5,null,2
    union all
    SELECT 6,null,5


    Select tm.Id,ISNULL(tb.Name,ta.Name) As NAME from @tableMain tm
    LEFT JOIN @tableB tb on tm.FktoB=tb.IDb and IDb is not NUll
    LEFT JOIN @tableA tA on tm.FktoA=ta.IDA and FktoB is NUll

You want to select from table A only when there is no match in table B, so given foreign keys are intact:

select 
  coalesce(b.firstname, a.firstname) as firstname,
  coalesce(b.surname, a.surname) as surname,
  coalesce(b.birthday, a.birthday) as birthday,
  ...
from MAIN m
left join TableB b on b.IDB = m.FKtoB
left join TableA a on a.IDA = m.FKtoA and m.FKtoB is null;

Another approach would be union all:

select firstname, surname, birthday, ...
from TableB 
where IDB in (select FKtoB from MAIN)
union all
select firstname, surname, birthday, ...
from TableA 
where IDA in (select FKtoA from MAIN where FKtoB is null);

Try this. It will give result as you want.

(select ida as ID ,
case when ida is not null then ida end fkToIda,
 case when idb is not null then idb end fkToIdB 
 from A
left outer join B on a.ida=b.idb)

union

(select idb ,
case when ida is not null then ida end,
 case when idb is not null then idb end 
 from A
right outer join B on a.ida=b.idb)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM