Home > Software design >  Eliminating null values in union
Eliminating null values in union

Time:06-23

I'm doing a query across databases with an identical structure, to show a mapping from a source value to a target value.
Every one of my databases has a table with two columns: source and target

DB1

Source Target
A X
A Y
B NULL
C NULL

DB2

Source Target
A NULL
A Y
B Z

So my query is

Select t.Source, t.Target
from DB1.table t
union
Select t.Source, t.Target
from DB2.table t

What I'm getting is

Source Target
A X
A Y
B NULL
C NULL
B Z
A NULL

But I'm only interested in the target being NULL, if there is no other mapping present. So I'm looking for the following result:

Source Target
A X
A Y
C NULL
B Z

How can I easily eliminate the highlighted rows A | NULL and B | NULL from my results?

I've seen a few answers suggesting using MAX(Target), but that won't work for me since I can have multiple valid mappings for a single source (A | X and A | Y)

CodePudding user response:

Something like this would work, just give a number based on NULL, and select the first:

SELECT  TOP(1) WITH TIES UN.Source
,       UN.Target
FROM    (
            Select t.Source, t.Target
            from DB1.table t
            union
            Select t.Source, t.Target
            from DB2.table t
        ) AS UN
ORDER BY DENSE_RANK()OVER(PARTITION BY UN.Source ORDER BY CASE WHEN UN.Target IS NOT NULL THEN 1 ELSE 2 END)

CodePudding user response:

You might find it easier to think in terms of minimums:

with data as (
    select Source, Target from DB1.<table> union
    select Source, Target from DB2.<table>
), qualified as (
    select *,
        case when Target is not null or min(Target) over (partition by Source) is null
             then 1 end as Keep
    from data
)
select Source, Target from qualified where Keep = 1;
  • Related