My MySQL returns empty set when I join on a common value UPC. I can do a left join and see the same UPC value on the right side when I do a right join. Why does an inner join return empty set then???? How do I make the join work??
MySQL>
select
upc_descriptions.UPC,
left(upc_descriptions.Description,15) as Description,
product_upc.ProductCode, product_upc.UPC
from upc_descriptions
left join product_upc
ON upc_descriptions.UPC=product_upc.UPC
where upc_descriptions.UPC = 009326204994;
| UPC | Description | ProductCode | UPC |
+--------------+-----------------+-------------+------+
| 009326204994 | KWIKSET PRO ADJ | NULL | NULL |
| 009326204994 | KWIKSET PRO ADJ | NULL | NULL |
+--------------+-----------------+-------------+------+
2 rows in set (0.04 sec)
MySQL>
select
upc_descriptions.UPC,
upc_descriptions.Description,
product_upc.ProductCode,
product_upc.UPC
from upc_descriptions
right join product_upc
ON upc_descriptions.UPC=product_upc.UPC
where product_upc.UPC = 009326204994;
+------+-------------+-------------+-----------------+
| UPC | Description | ProductCode | UPC |
+------+-------------+-------------+-----------------+
|NULL | NULL | 239070 | 009326204994
|NULL | NULL | 239070 | 00009326204994
+------+-------------+-------------+-----------------+
2 rows in set, 2 warnings (0.03 sec)
MySQL>
select
upc_descriptions.UPC,
upc_descriptions.Description,
product_upc.ProductCode,
product_upc.UPC
from upc_descriptions
inner join product_upc
ON upc_descriptions.UPC = product_upc.UPC
where product_upc.UPC = 009326204994;
Empty set (0.03 sec)
Table definitions:
mysql> describe upc_descriptions;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| UPC | varchar(20) | NO | | NULL | |
| Description | varchar(256) | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> describe product_upc;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ProductCode | varchar(50) | NO | | NULL | |
| UPC | varchar(20) | NO | | NULL | |
+-------------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
Here's the values that were loaded into the table.
cat productCode-UPC_sorted.csv | grep 009326204994
239070,009326204994
239070,00009326204994
kid927 suggested casting as SIGNED when defining the index tables to join. At first I thought this was going to work really well, but then as I dug deeper I ran into another strange problem. Here's the query and result:
mysql>
select
upc_descriptions.UPC,left(upc_descriptions.Description,15) as Description,
product_upc.ProductCode, product_upc.UPC
from upc_descriptions left join product_upc
ON CAST(upc_descriptions.UPC as SIGNED)=CAST(product_upc.UPC as SIGNED)
where upc_descriptions.UPC = 009326204994;
| UPC | Description | ProductCode | UPC |
+--------------+-----------------+-------------+-----------------+
|9326204994 | KWIKSET PRO ADJ | 239070 | 009326204994
|9326204994 | KWIKSET PRO ADJ | 239070 | 009326204994
|009326204994 | KWIKSET PRO ADJ | 239070 | 00009326204994
|009326204994 | KWIKSET PRO ADJ | 239070 | 00009326204994
+--------------+-----------------+-------------+-----------------+
4 rows in set, 65535 warnings (0.07 sec)
Where things get really weird is when I remove the WHERE clause and just look at the data that is joined. I get strange results where mysql matches one string to a substring of the other table producing a wrong result. This only makes sense if it is doing a CHAR type string comparison, but when I explicitly cast the UPC data as a SIGNED int, it should be comparing numbers and not doing sub-string comparisons... so I'm really confused about what's going on here. Here's an example:
mysql>
SELECT
upc_descriptions.UPC,
left(upc_descriptions.Description,15) as Description,
product_upc.ProductCode,
product_upc.UPC
FRP, upc_descriptions INNER JOIN product_upc
ON CAST(upc_descriptions.UPC as SIGNED)=CAST(product_upc.UPC as SIGNED);
| UPC | Description | ProductCode | UPC |
+--------------+-----------------+-------------+-----------------+
| 4036280125 | PASS PRO SERIES | 21096285 | 694036280125
| 4036960027 | KWIKSET PRO SIN | 21099030 | 694036960027
+--------------+-----------------+-------------+-----------------+
913 rows in set, 65535 warnings (21.33 sec)
See how the UPC in the left table (4036280125) returns a match to the right table where it is a substring in the number (694036280125). This looks like a string/char match despite the fact that I cast it as SIGNED. Further, this is wrong, because the number in the right table (694036280125) refers to a completely different product.