I want to find the record which has the same ID and indicator but with different value. Here is my sample data.
declare @table1 table (id int, indicator varchar(20),value int);
INSERT INTO @table1 VALUES
(11,'AC',80),
(11,'HE',90),
(12,'AC',10),
(12,'HE',80),
(13,'AC',10),
(13,'HE',10);
declare @table2 table(id int, indicator varchar(20),value int);
INSERT INTO @table2 VALUES
(11,'AC',80),
(11,'HE',90),
(12,'AC',11),
(12,'HE',80),
(13,'AC',10),
(14,'AC',10);
I create db<>fiddle
Base on the sample data above, there will 4 scenarios:
11 existing in both table, each ID with same indicator and value, so I will NOT log in record.
12 with indicator 'AC' has different value from table2 (10 and 11), this is the record I need.
13 existing in both table, but table 1 has 2 records, and both indicator 'AC' has same value. In this case, I only need the one which does not have match record in table 2.(In this case, its (13,'HE',10). Please notes, there could have same situation in table 2 as well. therefore, Result for table 1 will become NULL and list the result from table 2
ID only existing in one of the table, for eg: 14. Then I don't need this one.
In another word, I need the record If 2 table has same ID and Indicator but with different value. If both table has same ID, but with different indicator and value, I also need to log this record.
Therefore, I do want my result to look like this.
| Table 1 ID | Table 1 Indicator | Table 1 Value | Table 2 ID | Table 2 Indicator | Table 2 Value |
| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ |
| 12 | AC | 10 | 12 | AC | 11 |
| 13 | HE | 10 | NULL | NULL | NULL |
4条答案
按热度按时间2ul0zpep1#
Or without a join:
db<>fiddle for both.
x33g5p2x2#
This is a variation on the XOR join: you need to
FULL JOIN
the two sides, but only take the results if there is a difference. The tweak here is that if theID
does not exist on one side then you also want to ignore those rows (similar to anINNER JOIN
).The best I can come up with is to use a
FULL JOIN
combined wth conditional windowed counts of both sidesdb<>fiddle
Note that the fiddle also works for your extra case of
(13,'LE',10)
in table 2.The logic here is as follows:
First full-join everything together, this will get us all rows from both sides, but matched by
id
andindicator
.Calculate window counts based on: group by
id1
and count the number of matches forid2
, and the same in reverse. Do not calculate the count for any null group.Then filter as follows:
If the two
value
s are different (but neither are null) then we have a match, so include.If one side is null but there exist that
id
from the other side then include.And the same the other way
w6lpcovy3#
I have tried to add more records to @table1 and @table2 as you said:
Please check if this fulfills your requirements.
eufgjt7s4#