简体   繁体   中英

Table Comparison with NULL value

I'm looking for the best way to compare two tables and return the rows which contain differences between two tables.

//TABLE A

CREATE TABLE `mydb`.`a` (
  `id` int(10) unsigned NOT NULL,
  `color` varchar(45) DEFAULT NULL,
  `animal` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `mydb`.`a` 
    (id,color,animal) 
VALUES 
    (1,"red",""),
    (2,"blue","cat"),
    (3,"green","dog");
    (4,"orange","fish");

//TABLE B

CREATE TABLE `mydb`.`b` (
  `id` int(10) unsigned NOT NULL,
  `color` varchar(45) DEFAULT NULL,
  `animal` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `mydb`.`b` 
    (id,color,animal) 
VALUES 
    (1,"red",""),
    (2,"blue","cat"),
    (3,"green","bird");
    (4,"brown","fish");

The statement would return rows 3,4 of table B since bird and brown is different then dog and orange .

NULL represent lack of information. It will never match to other values (including other NULLs). So, for example, while zero is equal zero:

SQL> select case when 0 = 0 then 'true' else 'false' end ;
case when 0 = 0 then 'true' else 'false' end
--------------------------------------------
true                                    

NULL is not equal NULL:

SQL> select case when null = null then 'true' else 'false' end ;
case when null = null then 'true' else 'false' end
--------------------------------------------------
false                             

you will have to convert NULL to other values (for example zero) if you want to match them:

SQL> select case when ifnull(null, 0) = ifnull(null, 0) then 'true' else 'false' end ;
case when ifnull(null, 0) = ifnull(null, 0) then 'true' else 'false' end
------------------------------------------------------------------------
true   

EDIT

Assuming you have:

mysql> select * from a;
+----+--------+--------+
| id | color  | animal |
+----+--------+--------+
|  1 | red    |        |
|  2 | blue   | cat    |
|  3 | green  | dog    |
|  4 | orange | fish   |
+----+--------+--------+
4 rows in set (0.00 sec)

mysql> select * from b;
+----+-------+--------+
| id | color | animal |
+----+-------+--------+
|  1 | red   |        |
|  2 | blue  | cat    |
|  3 | green | bird   |
|  4 | brown | fish   |
+----+-------+--------+
4 rows in set (0.00 sec)

I would use:

mysql> select b.* from b left outer join a on a.id = b.id and 
       a.animal = b.animal and a.color = b.color 
       where a.id is null and a.animal is null and a.color is null ;
+----+-------+--------+
| id | color | animal |
+----+-------+--------+
|  3 | green | bird   |
|  4 | brown | fish   |
+----+-------+--------+
2 rows in set (0.00 sec)

to find rows in B with differences from th corresponding rows in A. And:

mysql> select a.* from a left outer join b on a.id = b.id and 
       a.animal = b.animal and a.color = b.color 
       where b.id is null and b.animal is null and b.color is null ;
+----+--------+--------+
| id | color  | animal |
+----+--------+--------+
|  3 | green  | dog    |
|  4 | orange | fish   |
+----+--------+--------+
2 rows in set (0.00 sec)

to find rows in A different from the corresponding rows in B.

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