假设我有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 它声明: "这是预期的行为。 参数(字符串和数字)作为浮点数进行比较" ???
答案 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.ACountry
和B.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 |
+--------------------------------------+
注意:字符串操作可能会降低此连接的性能。修复源数据再次是更好的解决方案。