首页 \ 问答 \ 转换为整数后在字符串上JOIN(JOIN on a String After Converted to Integer)

转换为整数后在字符串上JOIN(JOIN on a String After Converted to Integer)

我在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声明相同。

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


好的...所以我很尴尬。 昨天我整天都在撞墙。 然后我今天早上来看看它,原来应该是LEFT JOIN ... ON ... = d.index设置为LEFT JOIN ... ON ... = d.title 。 我将在这个帖子上向所有人投票。 但我希望你们都投票给我和/或标记要关闭的问题。


I am trying to LEFT JOIN on a CHAR after it is converted to an INT. Like this:

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

This gives me the correct response if the index is greater than zero. But if the index is zero or an empty string, I get duplicates of the row for every directory title:

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

So I added a COALESCE statement to convert every empty string to a NULL value:

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

The COALESCE statement does give me the correct response (I tested the output of the function alone), but now I get NULL for every directory title, unless the index was set to 0, in which case I get the same result as before:

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 

What am I doing wrong?


As suggested, I got rid of the COALESCE statement, and swapped it out for a NULLIF statement:

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

But I am met with the same result as if I had the COALESCE statement.

I created a Fiddle of the examples I have provided, and strangely enough it gives me my desired result. But this is not the result I am getting in Workbench. The server is running an older version of MySQL (5.1 I think?) could that be the problem?


Okay... so I am pretty embarrassed. I was banging my head against the wall all day yesterday. Then I come in this morning and take a look at it, it turns out what was supposed to be LEFT JOIN ... ON ... = d.index was set to LEFT JOIN ... ON ... = d.title. I am going to up-vote everyone on this thread. But I hope you all down vote me and/or mark the question to be closed.


原文:https://stackoverflow.com/questions/36631823
更新时间:2023-10-13 16:10

最满意答案

而不是这个错误的任务

*q[2] = 10;

这是由于运算符优先级相当于

*( q[2] ) = 10;

结果,解除引用的指针q [2]未初始化并具有不确定的值。 你应该写得像

( *q )[2] = 10;

甚至只是喜欢

q[0][2] = 10;

另一种方法是引入一个中间变量并使用它来初始化数组的元素。 例如

char *p = *q;

p[2] = 10;

这允许使用指针来逃避这种错误。


Instead of this wrong assignment

*q[2] = 10;

that is due to the operator precedence equivalent to

*( q[2] ) = 10;

and as result the dereferenced pointer q[2] is uninitialized and has indeterminate value. You should write either like

( *q )[2] = 10;

or even just like

q[0][2] = 10;

Another way is to introduce an intermediate variable and use it to initialize elements of the array. For example

char *p = *q;

p[2] = 10;

This allows to escape that kind of errors with pointers.

相关问答

更多
  • 如果我已经正确理解你在调用函数之前没有声明数组。 看来你声明了一个指向int而不是数组的指针。 否则,如果您确实声明了一个数组,那么您可能不会更改其大小并在函数中分配内存。 至少有三种方法可以完成任务。 第一个看起来像 int *f() { size_t n = 10; int *p = new int[n]; return p; } 并且函数被称为 int *p = f(); 另一种方法是将函数的参数声明为指向int的指针类型。 例如 voif f( int **p ) { ...
  • 只需使用std::vector 。 这种东西正是它的用途。 Just use a std::vector. This kind of thing is exactly what it's there for.
  • 更改生成 void generate(struct student* students){ /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ int i; for (i = 0; i < 10; i++) { students[i].id = (rand()%10 + 1); students[i].sc ...
  • 你有一个初学者错误,因为你从main的值传递指针g 。 这意味着在reservation_en_memoire函数中,您只将内存分配给指针的副本,该函数在函数返回时消失(但指针指向的内存不会被分配,因此您有内存泄漏)。 然后当你在main函数中访问g时,它仍然是你在那里声明的未初始化的指针,并且你有未定义的行为。 要使其工作,您必须通过引用传递指针,即作为指针的指针。 void reservation_en_memoire(int n, GRAPHE **g) { *g = malloc(sizeo ...
  • 如果它是单个字节,则根本没有理由进行内存分配。 你可以声明一个byte类型的局部变量并传递它。 当需要分配元素数组时,您需要使用malloc() ,并且在编译时您不知道元素的数量。 当您需要分配一个需要在创建它的函数退出后需要在内存中保留的大型结构时,您还需要它。 如果你正在处理一个基本类型的变量,那么你应该简单地声明它是一个局部变量,这意味着它将被自动分配到堆栈上。 If it is a single byte, there is no reason to do memory allocation at ...
  • 我遵循两个非常简单的规则,这使我的生活更轻松。 1 /只要你知道你需要什么,当你需要时分配记忆。 这可以让你在做太多工作之前捕捉内存不足的错误。 2 /每个分配的内存块都有责任属性。 当责任通过功能接口时应该很清楚,在这一点上释放内存的责任通过内存。 这将保证有人明确指定要求释放该内存。 在你的特定情况下,如果你想要返回给调用者的值,你需要传入一个双字符指针: int validate_input (const char *input_line, char **out_value_ptr) { : ...
  • 如果我将任何一个数组移动到函数外部并使其成为全局变量(文件级变量),那么它将在全局变量分配到堆上时起作用。 这是错误的假设。 定义在文件范围内的数组很可能放置在数据段内 ,或者更确切地说放在.bss段内,因为没有给出明确的初始化器。 但我不想让我的变量成为全局的。 是不是可以使用malloc和calloc为数组动态分配内存? 使用malloc和friends可以动态分配内存。 但是,因为在编译时已知大小,所以更好的选择可能会声明两个数组都是static : void SimpleTextEditor() { ...
  • 而不是这个错误的任务 *q[2] = 10; 这是由于运算符优先级相当于 *( q[2] ) = 10; 结果,解除引用的指针q [2]未初始化并具有不确定的值。 你应该写得像 ( *q )[2] = 10; 甚至只是喜欢 q[0][2] = 10; 另一种方法是引入一个中间变量并使用它来初始化数组的元素。 例如 char *p = *q; p[2] = 10; 这允许使用指针来逃避这种错误。 Instead of this wrong assignment *q[2] = 10; that ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)