mysql - JOIN 转换为整数后的字符串

标签 mysql sql join sql-convert

CHAR 转换为 INT 后,我正在尝试 LEFT JOIN。像这样:

SELECT o.title, d.title FROM original o
LEFT JOIN directory d ON CONVERT(o.directory_index, UNSIGNED INT) = d.index

如果索引大于零,这会给我正确的响应。但是如果索引为零或空字符串,我会得到每个目录标题的行的副本:

o.title       (o.index)    d.title          (d.index)

"Big Boss"    "2"          "OUTER HEAVEN"    2
"Snake"       "0"          "FOX"             0
"Snake"       "0"          "FOXHOUND"        1
"Snake"       "0"          "OUTER HEAVEN"    2
"Kerotan"     ""           "FOX"             0
"Kerotan"     ""           "FOXHOUND"        1
"Kerotan"     ""           "OUTER HEAVEN"    2

所以我添加了一个 COALESCE 语句来将每个空字符串转换为一个 NULL 值:

SELECT o.title, d.title FROM original o
LEFT JOIN directory d ON CONVERT(
    CASE WHEN COALESCE(o.directory_index, '') = '' THEN NULL ELSE o.directory_index END,
    UNSIGNED INT
) = d.index

COALESCE 语句确实给了我正确的响应(我单独测试了函数的输出),但现在我得到每个目录标题的 NULL,除非索引被设置为 0,在这种情况下我得到与之前相同的结果:

o.title       (o.index)    d.title          (d.index)

"Big Boss"    "2"          NULL              2
"Snake"       "0"          "FOX"             0
"Snake"       "0"          "FOXHOUND"        1
"Snake"       "0"          "OUTER HEAVEN"    2
"Kerotan"     ""           NULL              0
"Kerotan"     ""           NULL              1
"Kerotan"     ""           NULL              2 

我做错了什么?


按照建议,我去掉了 COALESCE 语句,并将其换成 NULLIF 语句:

SELECT o.title, d.title FROM original o
LEFT JOIN directory d ON CONVERT(
    NULLIF(o.directory_index, ''),
    UNSIGNED INT
) = d.index

但我得到的结果与我使用 COALESCE 语句时的结果相同。

我创建了一个 Fiddle我提供的例子中,奇怪的是它给了我我想要的结果。但这不是我在 Workbench 中得到的结果。服务器运行的是较旧版本的 MySQL(我认为是 5.1?)这可能是问题所在吗?


好吧……所以我很尴尬。我昨天一整天都在用头撞墙。然后我今天早上来看一看,原来应该是 LEFT JOIN ... ON ... = d.index 被设置为 LEFT JOIN 。 .. ON ... = d.title.我要在这个线程上给每个人投票。但我希望你们都给我投反对票和/或将问题标记为关闭。

最佳答案

COALESCE 不会用 NULL 值替换空字符串。相反,它返回列表中的第一个非 NULL 表达式。

要用 NULL 替换零长度字符串,您可以使用多种表达式...

 NULLIF(expr,'')

 IF(expr='',NULL,expr)

 CASE WHEN expr = '' THEN NULL ELSE expr END

要将字符串 (CHAR, VARCHAR) 表达式转换为数值,您可以使用 as shorthand:

expr + 0 

但这并不能保证返回一个 UNSIGNED INT,甚至是一个整数值。


原始答案如下

这里缺少的是 `directory` 表中的 `directory_index` 列和 `original` 表中的 `index` 列的定义。

这些列的数据类型是什么?它们中的任何一个都可以为空,还是唯一的?是否存在外键关系?

如果我们不知道您要实现的目标,就不可能回答您的问题“我做错了什么”。

乍一看,连接条件看起来比它需要的要复杂得多。

你能解释为什么这个不起作用(或不会)吗?

SELECT o.title
     , d.title
  FROM original o
  LEFT
  JOIN directory d 
    ON d.directory_index = o.index
 ORDER BY ...

您试图通过在连接条件中添加函数来解决什么问题

您似乎知道数据类型转换(从 CHAR 到 INT 等),而且您似乎知道 MySQL 会隐式地进行大量数据类型转换。您可以显式地进行这些数据类型转换,并且可以覆盖 MySQL 默认执行的操作。

在数字上下文中,MySQL 会将空字符串评估为值 0,而不是 NULL。作为一个简单的演示,

SELECT '' + 0 

但是,再次强调一下,您要实现的目标是什么?

这是少量样本数据的地方,预期的输出将阐明规范。

如何实现该结果实际上取决于表达式中使用的列的实际数据类型,以及您想要返回的内容。

我们提出的任何“试试这个”建议都只是猜测,而不是答案。

关于mysql - JOIN 转换为整数后的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36631823/

相关文章:

mysql - 在查询生成器中查询不同的行

mysql - Chart.js 雷达图多个数据集

mysql - 从相同的 MySQL 链接服务器表 Where 子句更新本地 MSSQL 表

SQL Server 2012链接服务器应用程序意图

sql - 通过附加数字将重复值转换为非重复值

MySQL - 如何 GROUP BY 更多列和 SUM() 每组?

mysql - 如何避免在 mysql 中外键有两个空值?

ruby-on-rails - Rails ActiveRecord :joins with LEFT JOIN instead of INNER JOIN

mysql - 需要根据表 1 元素条件将表行转换为另一个表中的列

mysql - sql join 返回具有空值的字段