MySQL在不同类型的字段上连接表

时间:2015-01-12 15:03:45

标签: mysql join

假设我有2个InnoDB表A和B.

Table A has a column named Acountry of type INT
Table B has a column named Bcountry of type VARCHAR

Some records in table A have in column Acountry values "356"
Some records in table B have in column Bcountry values "356,Italy"

以下联接如何完美地运作: (我的意思是我得到Acountry或Bcountry以356开头的行)

SELECT A.Field1 , A.Field2 , B.Field3 , B.Field4 
FROM A
JOIN B ON A.Acountry=B.Bcountry

尽管2列具有不同的值 并且是不同类型的

任何提示? 是否有任何设置"松散"加入?

P.S。 我找到了这个链接http://bugs.mysql.com/bug.php?id=3777 它声明: "这是预期的行为。 参数(字符串和数字)作为浮点数进行比较" ???

1 个答案:

答案 0 :(得分:2)

使用数字开始的MySQL中的字符串将被转换为第一个非数字字符的数字。因此,强制转换操作只会产生前面的整数:

> SELECT CAST('356,Italy' AS INT);
+--------------------------+
| CAST('356,Italy' AS INT) |
+--------------------------+
|                      356 |
+--------------------------+

(注意:转换为DECIMAL将产生相同的结果)

但是首先会将非数字字符的类似字符串转换为0

> SELECT CAST('xx356,Italy' AS INT);
+--------------------------------+
| CAST('xx356,Italy' AS INT)     |
+--------------------------------+
|                              0 |
+--------------------------------+

我认为这是一个不可靠的行为来执行连接,即使它在将来的MySQL版本中不太可能被更改。在这些公共列之间产生一致或更直接可比的值会好得多。

尽可能修复数据:

首先,如果您可以更改此表结构以使B具有一致的数据,那就是真正的解决方案。这样做还可以使A.ACountryB.BCountry的数据类型相同(均为INT类型),这进一步允许您定义正确的FOREIGN KEY约束。

使用字符串操作加入您所拥有的内容:

但是JOIN的{​​{1}}条件可以是任意表达式,并且MySQL提供SUBSTRING_INDEX() function以在分隔符之前返回子字符串。您应该能够使用它成功加入:

ON

这是因为:

SELECT
  A.*,
  B.Field3,
  B.Field4
FROM
  A
  -- Join on the first group of characters before `,` in BCountry
  INNER JOIN B ON A.ACountry = SUBSTRING_INDEX(BCountry, ',', 1)

没有尾随字符串的结果相同:

> SELECT SUBSTRING_INDEX('356,Italy', ',', 1);
+--------------------------------------+
| SUBSTRING_INDEX('356,Italy', ',', 1) |
+--------------------------------------+
| 356                                  |
+--------------------------------------+

注意:字符串操作可能会降低此连接的性能。修复源数据再次是更好的解决方案。