December 2, 2005 at 7:12 am
Hello,
I have two table that contain the same primary keys. Sometimes on table is missing data. How can I execute a querry that returns only the record from either table that does not exist in the other table?
Thanks,
December 2, 2005 at 7:45 am
something like this:
declare @Foo table (
dbkey int,
dbdata varchar(10))
declare @foo2 table (
dbkey int,
dbdata varchar(10))
insert into @Foo values (1,'one')
insert into @Foo values (2,'two')
insert into @Foo values (5,'five')
insert into @foo2 values (1,'one')
insert into @foo2 values (2,'two')
insert into @foo2 values (3,'three')
select 'In @Foo not in @foo2' record_state,
f.dbkey,
f.dbdata
from @Foo f
left outer join @foo2 f2
on f.dbkey = f2.dbkey
where f2.dbkey is null
union
select 'In @foo2 not in @Foo' record_state,
f2.dbkey,
f2.dbdata
from @foo2 f2
left outer join @Foo f
on f2.dbkey = f.dbkey
where f.dbkey is null
December 2, 2005 at 8:01 am
Or use a full outer join
select case when f.dbkey is null then 'In @foo' else 'In @foo2' end as record_state, f.dbkey as f_dbkey, f2.dbkey as f2_dbkey, f.dbdata as f_dbdata, f2.dbdata as f2_dbdata from @foo f full outer join @foo2 f2 on f.dbkey = f2.dbkey where (f2.dbkey is null) or (f1.dbkey is null)
It all depends on how you want the data - the union might give nicer results since it effectively treats both tables equally (first query is A not B, then next is B not A) - the full outer join doesn't mask this - you get the values from both tables in a single row (although this may suit you better)...
Good to have options in any case
December 2, 2005 at 8:36 am
Thanks, both of those I will find useful. Great Job.
I am curious to Ian's response. I tried yours too, and don't under the results,
here is what I came up with
use rsms
declare @StartDate NVARCHAR(24)
declare @EndDate NVARCHAR(24)
SET @startdate ='11/28/2005 07:00:00'
SET @enddate='11/29/2005 07:00:00'
select
case when B.[START DATE/TIME] is null then 'In B' else 'In A' end as record_state,
B.[START DATE/TIME] AS RSMS_DT, A.[START_DATE_TIME] AS RML2_DT
from [history-roll ground] B
full outer join RML2..RM.RM_RS_HISTORY_ROLL_GROUND A
on B.[START DATE/TIME] = A.[START_DATE_TIME]
where ((A.[START_DATE_TIME] is null) or (B.[START DATE/TIME] is null) AND
(A.start_date_time between @StartDate AND @enddate))
ORDER BY A.[START_DATE_TIME] DESC
and the results were
In B NULL 2005-11-29 06:00:48.000
In B NULL 2005-11-29 04:52:59.000
In B NULL 2005-11-29 04:08:58.000
In B NULL 2005-11-28 17:33:10.000
In B NULL 2005-11-28 16:11:47.000
In A 2005-08-24 03:07:24.000 NULL
In A 2005-08-24 10:59:06.000 NULL
In A 2005-12-01 06:33:10.000 NULL
the records on A are outside of the date range, how did they get there. I tried a few different varations of the where clause, but guess I don't full understand what is going here. Either way, the results from B were correct.
Thanks to both of you for the help.
Brian
December 2, 2005 at 8:54 am
Because the case statement is wrong. The rows that say "In B" are actually "In A" and vice-versa.
should be
case
when B.[START DATE/TIME] is null then 'In A'
else 'In B'
end as record_state
The results you show in your post actually DO meet the criteria. The record_state column just transposed the text.
December 4, 2005 at 4:31 am
Whoops!
Thanks for pointing that out
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply