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

MySQL joining tables on fields with different type

假设我有 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 列具有不同的值 并且属于不同类型

有什么提示吗? "loose"加入有什么设置吗?

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

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 版本中更改。在这些公共列之间产生一致或更直接的可比较值会好得多。

尽可能修复数据:

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

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

但是 JOINON 条件可以是任意表达式,而 MySQL 提供了 SUBSTRING_INDEX() function 到 return 分隔符前的子字符串.您应该能够使用它成功加入:

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                                  |
+--------------------------------------+

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

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

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