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.ACountry
和 B.BCountry
的数据类型相同(均为 INT
类型),这进一步允许您定义适当的 FOREIGN KEY
约束。
使用字符串操作加入您拥有的内容:
但是 JOIN
的 ON
条件可以是任意表达式,而 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 |
+--------------------------------+
注意:字符串操作可能会降低此连接的性能。修复源数据再次是更好的解决方案。
假设我有 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.ACountry
和 B.BCountry
的数据类型相同(均为 INT
类型),这进一步允许您定义适当的 FOREIGN KEY
约束。
使用字符串操作加入您拥有的内容:
但是 JOIN
的 ON
条件可以是任意表达式,而 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 |
+--------------------------------+
注意:字符串操作可能会降低此连接的性能。修复源数据再次是更好的解决方案。